Her zaman olduğu gibi, ™ bağlıdır. Cevap, birisinin çözmeye çalıştığı soruna bağlıdır. Bu cevapta, bazı genel motive edici güçleri ele almaya çalışacağım:
Küçük kod tabanlarını destekleyin
4.000 satırlık Spring yapılandırma kodunuz varsa, kod tabanının binlerce sınıfa sahip olduğunu varsayalım.
Bu durumdan sonra çözebileceğiniz bir sorun değil, ancak kural olarak, daha küçük kod tabanlarıyla daha küçük uygulamaları tercih etme eğilimindeyim. Eğer içine iseniz Domain-Driven Design , sen, örneğin, sınırlanmış bağlamda başına bir kod tabanı yapabiliriz.
Bu tavsiyeyi sınırlı deneyimlerime dayandırıyorum, çünkü kariyerimin çoğu için web tabanlı bir iş kolu kodu yazdım. Bir masaüstü uygulaması veya gömülü bir sistem veya başka bir yazılım geliştiriyorsanız, işlerin birbirinden ayrılmasının zor olduğunu hayal edebiliyorum.
Bu ilk tavsiyenin kolayca en az pratik olduğunu fark etmeme rağmen, bunun da en önemli olduğuna inanıyorum ve bu yüzden bunu ekliyorum. Kodun karmaşıklığı, kod tabanının boyutuna göre doğrusal olmayan (muhtemelen üstel olarak) değişir.
Favor Saf DI
Bu sorunun var olan bir durum olduğunu hala fark etmeme rağmen, Pure DI'yi tavsiye ediyorum . DI Konteyneri kullanmayın, ancak kullanırsanız en azından kongre tabanlı kompozisyon uygulamak için kullanın .
Spring ile ilgili pratik bir tecrübem yok, ancak yapılandırma dosyasında bir XML dosyasının ima edildiğini varsayıyorum .
Bağımlılıkları XML kullanarak yapılandırmak her iki dünyanın da en kötüsüdür. İlk olarak, derleme zamanı tür güvenliğini kaybedersiniz, ancak hiçbir şey kazanmazsınız. Bir XML yapılandırma dosyası kolayca değiştirmeye çalıştığı kod kadar büyük olabilir.
Ele almayı düşündüğü sorunla karşılaştırıldığında, bağımlılık enjeksiyon yapılandırma dosyaları, yapılandırma karmaşıklığı saatinde yanlış yer kaplar .
İri taneli bağımlılık enjeksiyonu için durum
İri taneli bağımlılık enjeksiyonu için bir vaka yapabilirim. İnce taneli bağımlılık enjeksiyonu için bir vaka da yapabilirim (bir sonraki bölüme bakınız).
Yalnızca birkaç 'merkezi' bağımlılık enjekte ederseniz, çoğu sınıf şöyle görünebilir:
public class Foo
{
private readonly Bar bar;
public Foo()
{
this.bar = new Bar();
}
// Members go here...
}
Bu hala uyuyor Tasarım Kalıpları 'ın sınıf miras üzerinde iyilik nesne kompozisyonu , çünkü Foo
oluşturur Bar
. Sürdürülebilirlik perspektifinden bakıldığında, bu hala sürdürülebilir olarak düşünülebilir, çünkü kompozisyonu değiştirmeniz gerekirse, sadece kaynak kodunu düzenlersiniz Foo
.
Bu bağımlılık enjeksiyonundan daha az bakım gerektirmez. Aslında, Bar
bağımlılık enjeksiyonuna özgü dolaylı olarak takip etmek yerine, kullanılan sınıfı doğrudan düzenlemenin daha kolay olduğunu söyleyebilirim .
Bağımlılık Enjeksiyonu kitabımın ilk baskısında, değişken ve istikrarlı bağımlılıklar arasında ayrım yapıyorum.
Geçici bağımlılıklar, enjekte etmeyi düşünmeniz gereken bağımlılıklardır. Onlar içerir
- Derlemeden sonra yeniden yapılandırılması gereken bağımlılıklar
- Başka bir ekip tarafından paralel olarak geliştirilen bağımlılıklar
- Deterministik olmayan davranışlara bağlı bağımlılıklar veya yan etkileri olan davranışlar
Öte yandan, istikrarlı bağımlılıklar iyi tanımlanmış şekilde davranan bağımlılıklardır. Bir anlamda, bu ayrımın kaba taneli bağımlılık enjeksiyonu için bir durum oluşturduğunu iddia edebilirsiniz, ancak kitabı yazarken bunu tamamen anlayamadığımı itiraf etmeliyim.
Bununla birlikte, test açısından bakıldığında bu birim testini zorlaştırır. Artık Foo
bağımsız bir birim test yapamazsınız Bar
. As JB Rainsberger açıklıyor , entegrasyon testleri karmaşıklık bir combinatoric patlama muzdarip. 4-5 sınıflarının bile entegrasyonu ile tüm yolları kapamak istiyorsanız, kelimenin tam anlamıyla on binlerce test senaryosu yazmanız gerekecek.
Bunun karşıt argümanı, sık sık sizin göreviniz bir sınıfı programlamak değildir. Göreviniz, belirli sorunları çözen bir sistem geliştirmektir. Davranış Odaklı Gelişme (BDD) arkasındaki motivasyon budur .
Bununla ilgili bir başka görüş, TDD'nin teste bağlı tasarım hasarına yol açtığını iddia eden DHH tarafından sunulmuştur . Ayrıca kaba taneli entegrasyon testinden yana.
Yazılım geliştirme üzerine bu perspektifi ele alırsanız, kaba taneli bağımlılık enjeksiyonu anlamlı olur.
İnce taneli bağımlılık enjeksiyonu için durum
İnce taneli bağımlılık enjeksiyonu, diğer taraftan, her şeyi enjekte etmek olarak tanımlanabilir !
İri taneli bağımlılık enjeksiyonuna ilişkin temel kaygım JB Rainsberger tarafından ifade edilen eleştiri. Tüm kod yollarını tümleştirme testleriyle kapatamazsınız, çünkü tüm kod yollarını kapsayacak şekilde tam anlamıyla binlerce veya on binlerce test senaryosu yazmanız gerekir.
BDD savunucuları, tüm kod yollarını testlerle kapamanız gerekmediği iddiasına karşı çıkacaktır. Sadece iş değeri üretenleri korumanız gerekir.
Bununla birlikte, benim deneyimlerime göre, tüm 'egzotik' kod yolları da yüksek hacimli bir dağıtımda yürütülecek ve test edilmezse, bunların çoğu kusurlu olacak ve çalışma zamanı istisnalarına neden olacaktır (genellikle boş referans istisnaları).
Bu, ince taneli bağımlılık enjeksiyonunu desteklememe neden oldu, çünkü tüm nesnelerin değişmezlerini yalıtılmış olarak test etmemi sağlıyor.
İşlevsel programlamayı tercih edin
İnce taneli bağımlılık enjeksiyonuna yaslanırken, diğer nedenlerin yanı sıra kendimi test edilebildiğim için işlevsel programlamaya vurgu yapıyorum .
SOLID koduna doğru ne kadar fazla hareket ederseniz, o kadar işlevsel hale gelir . Er ya da geç, daldırmayı da alabilirsin. Fonksiyonel mimari Limanlar ve Adaptörler mimarisidir ve bağımlılık enjeksiyonu da bir girişimdir ve Limanlar ve Adaptörler . Ancak fark, Haskell gibi bir dilin, bu mimariyi tip sistemi yoluyla zorlamasıdır.
Statik yazılan işlevsel programlamayı tercih edin
Bu noktada, temelde nesne yönelimli programlamadan (OOP) vazgeçtim, ancak OOP'nin sorunlarının çoğu Java ve C # gibi ana dillerle kavramın kendisinden daha fazla özdeşleştirilmiştir.
Ana akım OOP dilleri ile ilgili sorun, denenmemiş çalışma zamanı istisnalarına yol açan birleşimsel patlama sorununu önlemenin mümkün olmamasıdır. Diğer yandan, Haskell ve F # gibi statik olarak yazılmış diller, yazım sisteminde birçok karar noktasını kodlamanızı sağlar. Bu, binlerce test yazmak yerine derleyicinin, olası tüm kod yollarını ele alıp almadığınızı size söyleyeceği anlamına gelir (bir dereceye kadar; gümüş mermi yoktur).
Ayrıca, bağımlılık enjeksiyonu işlevsel değildir . Gerçek fonksiyonel programlama tüm bağımlılık kavramını reddetmelidir . Sonuç daha basit koddur.
özet
C # ile çalışmaya zorlanırsa, ince taneli bağımlılık enjeksiyonunu tercih ederim çünkü kod bazının tamamını yönetilebilir sayıda test vakası ile örtmeme olanak tanıyor.
Sonunda motivasyonum hızlı geri bildirim. Yine de ünite testi, geri bildirim almanın tek yolu değil .