Mutasyona uğrayan hiçbir şey sonunda durumu manipüle etmez mi?
Evet, ancak tüm sistemdeki özel durumunu değiştirebilen tek varlık olan küçük bir sınıfın üye işlevinin arkasındaysa, bu durumun çok dar bir kapsamı vardır.
Mümkün olduğunca az devletle uğraşmak için ne yapmanız gerekir?
Değişkenin bakış açısından: mümkün olduğu kadar az kod satırı erişebilmelidir. Değişkenin kapsamını minimuma indirir.
Kod satırının bakış açısından: bu kod satırından mümkün olduğunca az sayıda değişken erişilebilir olmalıdır. Kod satırının ki değişkenlerin sayısını daraltın muhtemelen erişim (hatta o olsun o kadar önemli değildir does hususlar bu olup olmadığıdır Hepsi bu erişim o can ).
Global değişkenler o kadar kötü ki maksimum kapsamı var. Bir kod tabanındaki 2 kod satırından, kod satırının POV'sinden erişilse bile, global bir değişkene her zaman erişilebilir. Değişkenin POV'sinden, dış bağlantıya sahip global bir değişkene, tüm kod tabanındaki her bir kod satırına (veya yine de başlığı içeren her bir kod satırına) erişilebilir. Yalnızca 2 satır kodla erişilmesine rağmen, global değişken 400.000 satır koduna görünürse, geçersiz bir duruma ayarlandığını gördüğünüzde anında şüphelenilen listenizin 400.000 girişi olacaktır (belki de Araçlarla 2 giriş, ancak yine de, acil listede 400.000 şüpheli olacak ve bu cesaret verici bir başlangıç noktası değildir).
Benzer şekilde, küresel bir değişken kod tabanının tamamında yalnızca 2 satır kodla değiştirilmeye başlasa bile, kod tabanlarının geriye doğru gelişmeye yönelik talihsiz eğilimi, bu sayıyı büyük ölçüde artırma eğiliminde olacaktır, çünkü geliştiriciler, son teslim tarihlerini karşılamak için çılgınca, bu küresel değişkeni görüyor ve bunun üzerinden kısayollar alabileceklerinin farkındalar.
C ++ gibi saf olmayan bir dilde, durum yönetimi gerçekten ne yaptığınızı değil mi?
Büyük ölçüde, evet, C + 'yı, özel yapım değişmez veri yapıları ve saf fonksiyonel programlama ile uğraştığınız çok egzotik bir şekilde kullanmadığınız sürece - aynı zamanda devlet yönetimi karmaşıklaştığında ve karmaşıklık olduğunda çoğu hatanın kaynağıdır. genellikle bu durumun görünürlüğünün / maruziyetinin bir fonksiyonu.
Değişken yaşam süresini sınırlamaktan başka mümkün olduğunca az durumla başa çıkmanın başka yolları nelerdir?
Bunların hepsi bir değişkenin kapsamını sınırlama alanındadır, ancak bunu yapmanın birçok yolu vardır:
- Veba gibi ham global değişkenlerden kaçının. Bazı aptal küresel ayarlayıcı / alıcı işlevi bile bu değişkenin görünürlüğünü büyük ölçüde daraltır ve en azından değişmezleri korumanın bir yolunu sağlar (örneğin: global değişkenin asla negatif bir değer olmasına izin verilmemesi durumunda, ayarlayıcı bu değişmezi koruyabilir). Tabii ki, aksi takdirde küresel bir değişken olacak bir setter / getter tasarımı bile oldukça zayıf tasarım, benim açımdan hala daha iyi olmasıdır.
- Mümkün olduğunca sınıflarınızı küçültün. Yüzlerce üye fonksiyonu, 20 üye değişkeni ve onu uygulayan 30.000 kod satırı olan bir sınıf, daha çok "global" özel değişkenlere sahip olacaktır, çünkü tüm bu değişkenler 30k kod satırından oluşan üye fonksiyonları için erişilebilir olacaktır. Bu durumda "durum karmaşıklığı" diyebilirsiniz, bu durumda her üye işlevindeki yerel değişkenleri iskonto ederken
30,000*20=600,000
. Bunun üstünde erişilebilir 10 küresel değişken olsaydı, devlet karmaşıklığı böyle olabilir 30,000*(20+10)=900,000
. Sağlıklı bir "devlet karmaşıklığı" (kişisel tür icat ettiğim metrik), on binlerce değil, kesinlikle yüz binlerce değil, sınıflar için binlerce veya altında olmalıdır. Serbest fonksiyonlar için, bakımda ciddi baş ağrıları görmeye başlamadan önce yüzlerce veya daha az diyelim.
- Yukarıdaki ile aynı şekilde, üye sınıf ya da arkadaş işlevi olarak, yalnızca sınıfın ortak arabirimini kullanan üye olmayan, arkadaş olmayan bir şey uygulamayın. Bu tür işlevler sınıfın özel değişkenlerine erişemez ve bu özel değişkenlerin kapsamını azaltarak hata olasılığını azaltır.
- Değişkenleri bir işlevde gerçekten ihtiyaç duyulmadan çok önce bildirmekten kaçının (örneğin, yalnızca çok sayıda satıra ihtiyaç duysalar bile, bir işlevin üstündeki tüm değişkenleri bildiren eski C stilinden kaçının). Bu stili yine de kullanırsanız, en azından daha kısa fonksiyonlar için çabalayın.
Değişkenlerin Ötesinde: Yan Etkiler
Yukarıda listelediğim bu yönergelerin birçoğu ham, değişken duruma (değişkenlere) doğrudan erişim ile mücadele ediyor. Ancak yeterince karmaşık bir kod tabanında, ham değişkenlerin kapsamını daraltmak, doğruluk hakkında kolayca akıl yürütmek için yeterli olmayacaktır.
Diyelim ki, tamamen SOLID, soyut bir arayüzün arkasında, değişmezleri mükemmel bir şekilde koruyabilen ve bu merkezi durumun geniş pozlaması nedeniyle hala çok fazla kederle karşılaşan merkezi bir veri yapısına sahip olabilirsiniz. Mutlaka küresel olarak erişilebilir olmayan ancak yalnızca geniş çapta erişilebilir olan bir merkezi durum örneği, bir oyun motorunun merkezi sahne grafiği veya Photoshop'un merkezi katman veri yapısıdır.
Bu gibi durumlarda, "devlet" fikri ham değişkenlerin ötesine geçer ve sadece veri yapılarına ve bu tür şeylere gider. Aynı şekilde kapsamlarını azaltmaya yardımcı olur (onları dolaylı olarak mutasyona uğratan işlevler çağırabilecek satır sayısını azaltın).
Geniş, uzaklaştırılmış mimari düzeyden dolaylı da olsa bu arayüze erişim hâlâ mutasyona uğradığı için arayüzü kasıtlı olarak burada kırmızı olarak nasıl işaretlediğime dikkat edin. Sınıf, değişmezleri arayüzün bir sonucu olarak koruyabilir, ancak bu sadece doğruluk hakkında akıl yürütme yeteneğimiz açısından çok ileri gider.
Bu durumda, merkezi veri yapısı küresel olarak erişilemeyen soyut bir arayüzün arkasındadır. Karmaşık kod tabanınızdaki bir tekne yükü işlevinden yalnızca enjekte edilebilir ve daha sonra dolaylı olarak (üye işlevleri aracılığıyla) dönüştürülebilir.
Böyle bir durumda, veri yapısı kendi değişmezlerini mükemmel bir şekilde muhafaza etse bile, daha geniş bir seviyede garip şeyler olabilir (örn: bir ses çalar, ses seviyesinin asla% 0 aralığının dışına çıkmaması gibi her türlü değişmezi koruyabilir % 100, ancak bu, oynat düğmesine basan ve bir etkinlik olarak oynatmaya en son yüklediği ses dışında rastgele bir ses klibine sahip olan kullanıcıyı korumaz, bu da oynatma listesinin geçerli bir şekilde yeniden karıştırılmasına neden olur, ancak hala istenmeyen, geniş kullanıcı perspektifinden glitchy davranışı).
Bu karmaşık senaryolarda kendinizi korumanın yolu, kod tabanındaki, ham durumun ötesine ve arayüzlerin ötesine geçen sistemin bu tür daha geniş bir görüşünden bile sonuçta harici yan etkilere neden olabilecek işlevleri "darboğaz" haline getirmektir.
Göründüğü kadar garip, hiçbir "durum" a (kırmızı ile gösterilen ve bu "ham değişken" anlamına gelmez, sadece bir "nesne" anlamına gelir ve muhtemelen soyut bir arayüzün arkasında) çok sayıda yerden erişildiğini görebilirsiniz. . İşlevlerin her biri, merkezi bir güncelleyici tarafından da erişilebilen bir yerel duruma erişebilir ve merkezi duruma yalnızca merkezi güncelleyici tarafından erişilebilir (artık merkezi değil, doğada yereldir).
Bu, yalnızca 10 milyon kod satırını kapsayan bir oyun gibi gerçekten karmaşık kod tabanları içindir, ancak yazılımınızın doğruluğu hakkında muhakemede büyük ölçüde yardımcı olabilir ve sayınızı önemli ölçüde sınırlandırdığınızda / tıklattığınızda değişikliklerinizin öngörülebilir sonuçlar verdiğini bulmak tüm mimarinin doğru işlev görmesi için döndüğü kritik durumları değiştirebilen yerler.
Ham değişkenlerin ötesinde dış yan etkiler vardır ve dış yan etkiler, birkaç üye işlevle sınırlı olsalar bile bir hata kaynağıdır. Bir tekne yükü işlevi, bu avuç üyesi işlevlerini doğrudan çağırabiliyorsa, sistemde dolaylı olarak harici yan etkilere neden olabilecek ve karmaşıklığı artıran bir tekne yükü işlevi vardır. Kod tabanında bu üye işlevlere erişimi olan tek bir yer varsa ve bir yürütme yolu her yerde sporadik olaylar tarafından tetiklenmezse, bunun yerine çok kontrollü, öngörülebilir bir şekilde yürütülürse, karmaşıklığı azaltır.
Devlet Karmaşıklığı
Devletin karmaşıklığı bile dikkate alınması gereken önemli bir faktördür. Soyut bir arayüzün arkasından geniş bir şekilde erişilebilen basit bir yapıyı karıştırmak o kadar da zor değildir.
Karmaşık bir mimarinin temel mantıksal temsilini temsil eden karmaşık bir grafik veri yapısını karıştırmak oldukça kolaydır ve grafiğin değişmezlerini bile ihlal etmeyecek şekilde. Bir grafik, basit bir yapıdan çok daha karmaşıktır ve bu nedenle böyle bir grafik yapısına erişimi olan yerlerin sayısını mutlak minimuma indirmek için kod tabanının algılanan karmaşıklığını azaltmak daha da önemli hale gelir, ve sporadik önlemek için bir çekme paradigmasını tersine çeviren bu tür "merkezi güncelleyici" stratejisi, her yerden grafik veri yapısına doğrudan itebilir.