Oldukça pragmatistim, ama burada asıl endişem, bunun ConfigBlock
arayüz tasarımlarınıza muhtemelen kötü bir şekilde hükmetmesine izin vermeniz olabilir . Böyle bir şey olduğunda:
explicit MyGreatClass(const ConfigBlock& config);
... daha uygun bir arayüz şöyle olabilir:
MyGreatClass(int foo, float bar, const string& baz);
... bu foo/bar/baz
tarlaları devasa bir tarladan almak yerine ConfigBlock
.
Tembel Arayüz Tasarımı
Artı tarafta, bu tür tasarım, kurucunuz için istikrarlı bir arayüz tasarlamayı kolaylaştırır, örneğin, yeni bir şeye ihtiyacınız varsa, bunu ConfigBlock
(muhtemelen herhangi bir kod değişikliği olmadan) ve daha sonra kiraz herhangi bir arabirim değişikliği olmadan ihtiyacınız olan her şeyi seçin, sadece uygulamasında bir değişiklik yapın MyGreatClass
.
Yani bu hem profesyonel hem de aleyhte bir şey. "Sadece bana bu büyük veri bloğunu verin, ondan neye ihtiyacım olduğunu seçeceğim" anlayışını uygular , "Bu kesin parametreler bu arayüzün çalışması için ihtiyaç duyduğu şeydir."
Yani burada kesinlikle bazı artılar var, ancak eksilerini ağır bastırabilirler.
Kavrama
Bu senaryoda, bir ConfigBlock
örnekten oluşturulan tüm sınıflar , bağımlılıklarının şöyle görünmesini sağlar:
Bu bir PITA olabilir, örneğin, Class2
bu diyagramda birim testi izole etmek istiyorsanız . Çeşitli koşullar altında test edebilmek için ConfigBlock
ilgili alanları içeren çeşitli girdileri yüzeysel olarak simüle etmeniz gerekebilir Class2
.
Her türlü yeni bağlamda (ister birim test olsun isterse tamamen yeni proje), bu tür sınıflar, her zaman ConfigBlock
sürüş için beraberinde getirmek ve kurmak zorunda kaldığımız için (yeniden) kullanım için daha fazla yük haline gelebilir . buna göre.
Yeniden kullanılabilirlik / konuşlandırılabilirliğini / Testedilebilirlik
Bunun yerine, bu arayüzleri uygun şekilde tasarlarsanız, bunları birbirinden ayırabilir ConfigBlock
ve bunun gibi bir şeyle sonuçlayabiliriz :
Yukarıdaki şemada fark ederseniz, tüm sınıflar bağımsız hale gelir (afferent / giden kaplinleri 1 azalır).
Bu ConfigBlock
, yeni senaryolarda / projelerde (yeniden) kullanılması / test edilmesi çok daha kolay olabilen çok daha bağımsız sınıflara (en azından bağımsız ) yol açar .
Şimdi bu Client
kod, her şeye bağlı ve hepsini bir araya getirmek zorunda olan kod haline geliyor. Yük, uygun alanları a'dan okumak ve ConfigBlock
parametre olarak uygun sınıflara aktarmak için bu istemci koduna aktarılır . Yine de, bu tür istemci kodu genellikle belirli bir bağlam için dar olarak tasarlanmıştır ve yeniden kullanım potansiyeli genellikle zilch veya yine de kapanır (uygulamanızın main
giriş noktası işlevi veya bunun gibi bir şey olabilir).
Bu nedenle, yeniden kullanılabilirlik ve test bakış açısından, bu sınıfları daha bağımsız hale getirmeye yardımcı olabilir. Sınıflarınızı kullananlar için arayüz açısından, ConfigBlock
her şey için gerekli olan tüm veri alanları evrenini modelleyen tek bir kitle yerine, hangi parametrelere ihtiyaç duyduklarını açıkça belirtmeye yardımcı olabilir .
Sonuç
Genel olarak, gereken her şeye sahip bir monolite dayanan bu tür bir sınıf odaklı tasarım, bu tür özelliklere sahip olma eğilimindedir. Uygulanabilirlikleri, konuşlandırılabilirlikleri, tekrar kullanılabilirlikleri, test edilebilirlikleri vb. Sonuç olarak önemli ölçüde bozulabilir. Yine de, üzerinde olumlu bir dönüş yapmaya çalışırsak, arayüz tasarımını basitleştirebilirler. Bu artıları ve eksileri ölçmek ve değiş tokuşların buna değip değmeyeceğine karar vermek size kalmış. Genellikle daha genel ve yaygın olarak uygulanabilir bir tasarımı modellemek için tasarlanan sınıflardaki bir monolitten kiraz seçtiğiniz bu tür tasarıma karşı hata yapmak daha güvenlidir.
Sonuncu ama bir o kadar önemli:
extern CodingBlock MyCodingBlock;
... bu, yukarıda açıklanan özellikler açısından bağımlılık enjeksiyon yaklaşımından daha kötüdür (daha fazla çarpık mı?), çünkü sınıflarınızı sadece belirli bir örneğeConfigBlocks
değil, doğrudan belirli bir örneğine de bağlar. Bu, uygulanabilirliği / konuşlandırılabilirliği / test edilebilirliği daha da bozmaktadır.
Genel tavsiyem, en azından tasarladığınız en genel olarak uygulanabilir sınıflar için parametrelerini sağlamak için bu tür monolitlere bağlı olmayan arayüzler tasarlama tarafında hata yapmaktır. Ve gerçekten kaçınmak için çok güçlü ve kendinden emin bir nedeniniz yoksa, bağımlılık enjeksiyonu olmadan küresel yaklaşımdan kaçının.