Bu, olumlu oylanan cevaba benziyor ancak ben yüksek sesle düşünmek istiyorum - belki başkaları da olayları bu şekilde görüyor.
Klasik OO, sınıfın tüketicileri için genel "başlatma" sözleşmesini tanımlamak için yapıcıları kullanır (TÜM uygulama ayrıntılarını gizleme; diğer adıyla kapsülleme). Bu sözleşme, somutlaştırmadan sonra kullanıma hazır bir nesneye sahip olmanızı sağlayabilir (yani, kullanıcı tarafından hatırlanacak ek başlatma adımları (unutulmuş) yoktur).
(yapıcı) DI , bu genel kurucu arayüzü aracılığıyla uygulama detayını akıtarak kapsüllemeyi inkar edilemez şekilde kırar . Halen kamu kurucusunu kullanıcılar için başlatma sözleşmesini tanımlamakla sorumlu olarak gördüğümüz sürece, korkunç bir kapsülleme ihlali yarattık.
Teorik Örnek:
Sınıf Foo'nun 4 yöntemi vardır ve başlatma için bir tamsayıya ihtiyaç duyar, bu nedenle kurucusu Foo (int boyut) gibi görünür ve Foo sınıfı kullanıcıları için bir boyut sağlamaları gerektiği hemen anlaşılır. Foo'nun çalışması için başlatmada .
Diyelim ki bu Foo uygulamasının işini yapmak için bir IWidget'e ihtiyacı olabilir . Bu bağımlılığın yapıcı enjeksiyonu, bize benzer bir kurucu oluşturmamızı sağlar. Foo (int size, IWidget widget)
Beni bu konuda endişelendiren, şimdi başlatma verilerini bağımlılıklarla harmanlayan bir kurucumuz var - bir girdi sınıfın ( boyut ) kullanıcısını ilgilendiriyor , diğeri ise yalnızca kullanıcının kafasını karıştırmaya yarayan ve bir uygulama olan dahili bir bağımlılık. detay ( widget ).
Boyut parametresi bir bağımlılık DEĞİLDİR - basit bir örnek başına başlatma değeridir. IoC, harici bağımlılıklar için uygundur (widget gibi) ancak dahili durum başlatma için uygun değildir.
Daha da kötüsü, ya Widget bu sınıftaki 4 yöntemden yalnızca 2'si için gerekliyse; Kullanılmasa bile Widget için örnekleme ek yüküne maruz kalıyorum!
Bunu nasıl uzlaştırabilirim / uzlaştırabilirim?
Bir yaklaşım, operasyon sözleşmesini tanımlamak için özel olarak arayüzlere geçmektir; ve yapıcıların kullanıcılar tarafından kullanımını kaldırır. Tutarlı olması için, tüm nesnelere yalnızca arabirimler aracılığıyla erişilmesi ve yalnızca bazı çözümleyici biçimleriyle (bir IOC / DI konteyneri gibi) somutlaştırılması gerekir. Yalnızca kapsayıcı şeyleri somutlaştırabilir.
Bu Widget bağımlılığını halleder, ancak Foo arayüzünde ayrı bir başlatma yöntemine başvurmadan "boyutu" nasıl başlatabiliriz? Bu çözümü kullanarak, siz örneği aldığınızda bir Foo örneğinin tamamen başlatıldığından emin olma yeteneğimizi kaybettik. Bummer, çünkü yapıcı enjeksiyon fikrini ve basitliğini gerçekten seviyorum .
Başlatma YALNIZCA dış bağımlılıklardan DAHA FAZLA olduğunda, bu DI dünyasında garantili başlatmayı nasıl elde ederim?