Bağımlılık enjeksiyonu: Hangi noktada yeni bir nesne oluşturabilirim?


13

Ben bir PHP uygulaması refactoring ve yapmaya çalışıyorum mümkün olduğunca çok bağımlılık enjeksiyon (DI) vardır.

Nasıl çalıştığını iyi anladım ve sınıflarımın çok daha yalın ve daha sağlam olduğunu görebiliyorum.

Sınıf içinde yeni bir nesne oluşturmak yerine bir bağımlılık enjekte edebilir, ancak bir noktada bazı nesneler oluşturmak zorunda kalacağım, yani, dreaded newanahtar sözcüğünü kullanmak için refactoring .

Şimdi karşılaştığım sorun hangi noktada gerçekten yeni nesneler oluşturabilirim? Görünüşe göre üst düzey bir sınıfa gidiyorum, gidecek başka bir yer olmadığı için bir sürü yeni nesne yaratıyorum. Bu yanlış geliyor.

Tüm nesneleri oluşturmak için fabrika sınıflarını kullanan bazı blogları okudum ve sonra fabrikayı diğer sınıflara enjekte ettiniz. Daha sonra fabrika yöntemlerini çağırabilirsiniz ve fabrika sizin için yeni nesneyi oluşturur.

Bunu yapma konusundaki endişem, şimdi fabrika derslerimin herkes için newücretsiz olacağı ! Sanırım bu fabrika sınıfları olarak iyi olabilir, ancak bir fabrika deseni ve DI kullanırken yapışacak bazı kurallar var mı, yoksa buradaki işaretin dışına gidiyorum?



Hizmetler ve politikalar için IoC'yi öneriyorum. Model veya yardımcı sınıflar için kullanacağım new. Tabii ki IoC kapsayıcısına çağırmanız gereken birkaç giriş noktası var, ancak çok fazla olmamalı. Genellikle IoC'yi bir kez yapılandırırsınız ve daha sonra istek başına bir sınıfın çözülmesini istersiniz. MVC söz konusu olduğunda bu genellikle denetleyicidir.
CodesInChaos

Bahsettiğiniz üst düzey sınıf Kompozisyon Kökünün bir parçasıdır. Yanlış olmaktan çok uzaktır.
Facio Ratio

Yanıtlar:


12

Bunun için biraz googling yaptıktan sonra, (yukarıda bir yorumda belirtildiği gibi) bahsettiğim en üst sınıf sınıfına Kompozisyon Kökü denir .

Gerçekten de bu Kompozisyon Kökü içindeki tüm nesnelerin oluşturulmasını eklemek için kabul edilen bir çözüm gibi görünüyor (veya buradan bir IoC kapsayıcısına atıfta bulunmak).

Bununla ilgili asıl endişem, bu üst düzey sınıfın biraz dağınık olmasıydı. Bu bir dereceye kadar doğrudur, ancak eksileri eksilerini tartmaktadır. Örneğin, diğer tüm sınıflarımın okunabilirliğinin, test edilebilirliğinin ve sürdürülebilirliğinin geliştiğini görebiliyorum.

Üst düzey sınıf biraz dağınık, çöp ile çevrili olabilir newve set_property()ben aslında tüm bu kod tüm diğer sınıflar hakkında dağınık yerine, tek bir yerde, tercih etmeliyim

Bu yöntemin bir diğer kullanışlı sayfa tartışırken performans isabet burada


1
+1 çünkü daha önce 'Composition Root'u hiç duymamıştım.
c_maker

2

Bir Fabrika sınıfı buna newserpilmiş olacak . İstediğiniz herhangi bir nesneyi ve muhtemelen o nesnenin bağımlılıklarını oluşturmak olacaktır. Fabrikaların işi, newbu sınıfta sahip olduğunuz için doğru nesneyi somutlaştırmak olduğundan kötü bir şey değildir.

DI, gevşek bir şekilde birleştirilmiş bir tasarıma sahip olmanız içindir. Her nesneye sağlanan bağımlılığı değiştirerek uygulamanızda değişiklik yapabilirsiniz. Uygulamanızı esnek, genişletilebilir ve test edilmesi kolay hale getirir.

En üst düzeyde, birkaç fabrikayı başlatan, hizmetlere bağlantı kuracak ve bir yanıt gönderecek kodunuz olacaktır. newUygulamanız için gerekli olan nesneleri somutlaştırmak için makul miktarda veya statik çağrılar olacaktır. Bu ait olduğu yer.


-2

Buradaki iki sentim:

Ben bir php uygulama refactoring ve yapmaya çalışıyorum mümkün olduğunca çok bağımlılık enjeksiyon vardır

Bir bağımlılık enjeksiyon çerçevesi kullanıp kullanmadığınızı belirtmezsiniz. Bence kesinlikle yapmalısın. Size ihtiyacınız olan özellikleri veren bir şey kullanın: /programming/9348376/guice-like-dependency-injection-frameworks-in-php .

Şimdi karşılaştığım sorun hangi noktada gerçekten yeni nesneler oluşturabilirim? Görünüşe göre, üst düzey bir sınıfa gidiyorum, gidecek başka bir yer olmadığı için yeni nesneler yükler. Bu yanlış geliyor.

Normalde, uygulamanızı oluşturan ilk nesnelerin somutlaştırılması için yapılandırma veya merkezi bir nokta kullanırsınız. Kap sizin için nesneleri oluşturacaktır.

Daha sonra nesnelere (hizmetler, sağlayıcılar, denetleyiciler ...) IoC kapsayıcısı üzerinden erişirsiniz. Gerekirse sizin için şeffaf bir şekilde bir nesne oluşturacak veya mevcut uygun örneğe bir referans verecektir.

Tabii ki, belirli nesne uygulamalarınız içinde DI'ye ihtiyacınız olmayan diğer nesneleri (veri yapıları, özel türler, vb.) Başlatabilirsiniz, ancak bu normal programlamadır.

Tüm nesneleri oluşturmak için fabrika sınıflarını kullanan bazı blogları okudum ve sonra fabrikayı diğer sınıflara enjekte ettiniz. Daha sonra fabrika yöntemlerini çağırabilirsiniz ve fabrika sizin için yeni nesneyi oluşturur.

Normalde, IoC çerçevesinin fabrikalarınız üzerinden bazı IoC nesnelerini başlatmasını istiyorsanız bir Fabrika kullanırsınız (bu, belirli bir nesneyi örneklemek için biraz fazladan çalışma gerektirir). Nesnelerinizi "yeni Object ()" ile oluşturabilir ve bazı özellikleri ayarlayabiliyorsanız, mutlaka bir Fabrika kalıbı kullanmak istemezsiniz.

Başka bir deyişle, bir sınıf veya sınıf grubu için bir Fabrika deseni kullanmanın, DI'yi kullanıp kullanmadığınıza değil (DI uygulamanız açıkça olağandışı olan fabrikaları gerektirmediği sürece), bu sınıfları nasıl modellemek istediğinize bağlı olduğunu söyleyebilirim.

IoC çerçevenizi, zaten bir Fabrika kullanımını gerektiren bir 3. taraf kitap kullanırken Fabrika kullanacak şekilde de yapılandırabilirsiniz. Bu durumda bunun üzerinde hiçbir kontrole sahip değilsiniz ve IoC konteynırınıza şunları söylemelisiniz: "hey, bu arayüzlerden birini istediğimde, bana uygun bir örnek sunmak için bu fabrikayı kullanmalısınız".

Bunu yapma konusundaki endişem, şimdi fabrika derslerimin herkes için yeni bir ücretsiz olacağı! Sanırım bu fabrika sınıfları olarak iyi olabilir, ancak fabrika kalıbı ve DI kullanırken yapışacak bazı kurallar var mı, yoksa buradaki işaretin dışına çıkıyorum.

Bu durumda, bu nesneler / hizmetler / denetleyiciler / herhangi bir şey için Fabrika desenlerini kullanmanız gerekmediği anlaşılıyor ve IoC'nizi uygun sınıfla "yeni" başlatacak ve diğer her şeyi enjekte edecek şekilde yapılandırabilirsiniz.

Umut ediyorum bu yardım eder.


cevap için teşekkürler, ama kesinlikle IoC kap bahsettiğim 'üst düzey sınıf'. Eğer orada sadece nesneler yaratabilirsem, bu doğru bir karmaşa olur.
Gaz_Edge

4
doing DI manually beats the whole purpose of using an Inversion of Control container- Bununla demek istiyorsan, "... bir yapılandırma dosyasındaki bağımlılıklarını merkezileştiriyor" demek istiyorsan, o zaman haklısın, çünkü hepsi bir IoC kapsayıcısının gerçekten yaptığı gibi. DI'nin asıl amacı ayrıştırmaktır ve bunu bir yapıcı yönteminde bağımlılıklarınızı sağlayarak yapabilirsiniz. Bunu yapmak için bir DI çerçevesine ihtiyacınız yok.
Robert Harvey

mmm nesneler oluşturmazsanız, IoC kapsayıcısını istersiniz (ihtiyacınız olan her yerden) veya alan / bağımsız değişken enjeksiyonunu kullanırsınız, böylece sınıflarınıza her zaman IoC kapsayıcısı tarafından oluşturulan uygun sınıfları otomatik olarak enjekte edilir.
jjmontes

1
Çok büyük uygulamalar için bir çerçeveye ihtiyacınız olduğunu kabul ediyorum . Birçok uygulama o kadar büyük değildir ve bir DI çerçevesi kullanmanın ek karmaşıklığından faydalanmaz.
Robert Harvey

2
Öyle olduğunu söylemedim. Basitçe bunu yapmak için DI kabına ihtiyacınız olmadığını söyledim.
Robert Harvey
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.