Dlaczego potrzebujemy ram do wstrzykiwania zależności? [Zamknięte]

42

Czytałem więcej na temat zasady Inversion of Control i Dependency Injection jako jej implementacji i jestem całkiem pewien, że ją rozumiem.

Wydaje się, że w zasadzie mówi „nie deklaruj instancji członków klasy w obrębie klasy”. Zamiast tego instancje powinny być przekazywane i przypisywane przez konstruktora; „wstrzyknięty” do klasy z zewnętrznego źródła.

Jeśli jest to takie proste, jak się wydaje, to po co nam ramy takie jak spring lub guice, które implementują to za pomocą adnotacji? Czy brakuje mi czegoś fundamentalnego? Naprawdę staram się zrozumieć, jakie są zastosowania struktur wstrzykiwania zależności.

Edycja: Jeśli chodzi o możliwy duplikat, uważam, że moje pytanie jest bardziej unikalne, ponieważ dotyczy ogólnie frameworków DI, a nie tylko wiosny. Wiosna to nie tylko środowisko DI, więc istnieje wiele powodów, dla których ktoś chciałby używać Springa, które nie są związane z DI.

timsworth
źródło
11
Są przydatne do przełączania błędów w środowisko wykonawcze zamiast czasu kompilacji.
Den
1
@den Dlaczego mielibyśmy to zrobić? Wydaje się, że narusza to szybkie niepowodzenie
TEN UŻYTKOWNIK POTRZEBUJE POMOCY

Odpowiedzi:

26

Nie potrzebujemy ram. Jest całkowicie możliwe ręczne wdrożenie wstrzykiwania zależności, nawet w przypadku stosunkowo dużego projektu.

Z drugiej strony użycie frameworka ułatwia, szczególnie oparte na adnotacjach lub automatycznym wykrywaniu zależności, ponieważ upraszcza cały proces: jeśli zdecyduję, że potrzebuję nowej zależności w klasie, wszystko co muszę zrobić, to dodać do konstruktora (lub deklaruje settera) i obiekt jest wstrzykiwany - nie muszę zmieniać żadnego kodu instancji.

Ponadto frameworki często zawierają inne przydatne funkcje. Na przykład Spring zawiera przydatne ramy dla programowania zorientowanego na aspekty, w tym deklaratywną rozgraniczenie transakcji (co jest bardzo przydatne) i różnorodne implementacje adapterów, które ułatwiają integrację wielu bibliotek stron trzecich.

Jules
źródło
8
Trafić w sedno. My nie są potrzebne. Ułatwiają życie przy dużych projektach. Szczerze mówiąc, uważam, że ramy są bardziej kłopotliwe niż warte mniejszych projektów. Zachęcam OP, aby nie myliła Dependency Injection z ramami, które ją obsługują.
RubberDuck,
1
dobrze powiedziane. I po co wymyślać koło, gdy ktoś inny stworzył już taki fajny i okrągły?
jwenting
Dokładnie to. Tyle że nie muszę zmieniać żadnego kodu instancji - oczywiście nie ma kodu instancji ;-)
Mathieu Guindon
Wygląda na to, że twoje biblioteki DI są do bani. Dobrzy mogą odgadnąć klasę, aby utworzyć instancję za pomocą odbicia.
Florian Margaine
2
każdy, kto używa refleksji do przetwarzania środowiska wykonawczego, robi to źle. Odbicie jest jedną z tych technologii, które tylko dlatego, że możesz coś zrobić, nie oznaczają, że powinieneś.
gbjbaanb,
12
  1. Dlaczego w ogóle potrzebujemy DI (Dependency Injection)?

    Mechanizm DI oddziela produkcję obiektu od zużycia obiektu. Zależności, których potrzebuje obiekt, są dostarczane w sposób transparentny z zewnątrz. Zaleta tego mechanizmu jest oczywista: w każdej chwili można zamienić zależności, np. Używając obiektu zerowego do celów testowych.

  2. Jak to jest zrobione?

    Istnieje kilka sposobów osiągnięcia celu:

    • Wstrzykiwanie zależności za pomocą wstrzykiwania konstruktora
    • Wtrysk przez getter / setter
    • Interfejs wtrysku
  3. Czy potrzebujemy frameworków DI?

    Nie, wcale nie. Możesz po prostu ręcznie przekazać wszystkie wystąpienia do innych obiektów. Jeśli masz małą aplikację, nie potrzebujesz pojemnika sprężynowego.

    Z drugiej strony frameworki pomagają w zarządzaniu obiektami:

    • Pomagają w okablowaniu złożonych relacji między obiektami. Nie musisz pisać żadnego kodu, aby wygenerować instancje i przekazać je do odpowiednich obiektów

    • Pomagają kontrolować, kiedy obiekt jest tworzony: możesz tworzyć instancje podczas ładowania aplikacji, ale w niektórych przypadkach leniwe tworzenie - tylko w razie potrzeby - jest lepsze

    • Pomagają kontrolować liczbę tworzonych instancji: jedną na cykl życia aplikacji lub jedną na żądanie (w przypadku programowania online)

Jeśli projekt ma odpowiedni rozmiar - jeśli czujesz potrzebę napisania mniejszego kodu - to ma sens przy użyciu frameworku (DI-). Jest więcej zalet niż wad.

Thomas Junk
źródło
2
Z bibliotek DI można korzystać bez korzystania z frameworka.
Florian Margaine,
5

Wiosną jest to głównie kwestia wygody.

Jeśli masz klasę, TopLevelktóra konstruuje klasę, MiddleLevelktóra konstruuje klasę LowLevel, i zdajesz sobie sprawę, że potrzebujesz nowego parametru konstruktora LowLevel, musisz również dodać go do TopLeveli MiddleLevelpo prostu, aby gdy nadszedł czas na MiddleLevelzbudowanie LowLevelwartości, wartość będzie dostępna dzięki czemu można go przekazać do konstruktora. Wiosną po prostu dodajesz adnotację.

Również wiosną możliwe jest zdefiniowanie zależności w zewnętrznym pliku konfiguracyjnym zamiast xml, a to rzekomo daje ci możliwość wygenerowania nowego systemu z zupełnie innym okablowaniem „bez zmiany kodu”. (IMHO jest to całkowicie błędnie skierowane, ponieważ zmiana xml nie różni się tak bardzo od zmiany kodu, a faktycznie kod zwykle ma znacznie lepsze sprawdzanie błędów i sprawdzanie typów niż xml.)

Inną rzeczą jest to, że wiele osób boi się konstruktorów; nie rozumieją ich, nie lubią ich, wolą ich nie używać.

Mike Nakis
źródło
3
W większości się zgadzają, szczególnie z uwagą XML. IMHO, obawa przed konstruktorami jest prawdopodobnie złym powodem do korzystania z frameworka DI.
Robert Harvey
2
IMHO, obawa przed konstruktorami jest dobrym powodem, aby trzymać się z dala od programowania. C -: =
Mike Nakis
5
Ale w jaki sposób ma to przewagę nad fabryką (statyczną lub inną)? (Co ma tę zaletę, że jest opcją, której można użyć odpowiednio, podczas gdy wiosna wydaje się być wszystkim albo niczym)
Richard Tingle
@RichardTingle Spring może stanowić zaletę głównie ze względu na wszystkie inne rzeczy, które robi oprócz DI, ponieważ oczywiście można osiągnąć DI na wiele innych sposobów, jednym z fabryk statycznych. (Jeden z najmniej fajnych, ale wciąż.) Pytanie dotyczy jednak tego, czy konieczne jest użycie sprężyny, aby uzyskać DI, i na to starałem się odpowiedzieć: w zasadzie nie jest to konieczne, tylko wygoda .
Mike Nakis,
To jest przykład tego, czym nie jest DI. „TopLevel” nie powinien tworzyć MiddleLevel, ale powinien otrzymać go podczas konstruowania TopLeveljako argument konstruktora. Podobnie MiddleLevelpowinien otrzymać LowLevelw swoim konstruktorze.
Jaśniejsze
1

Kilka lat temu napisałem program do monitorowania stron internetowych, portletów internetowych, a nawet niektórych tabel baz danych w firmie, w której kiedyś pracowałem. Chciałem, aby był na tyle elastyczny, aby użytkownik mógł określić, które monitory będą działać i przy jakich parametrach (adresy URL, loginy, kryteria sukcesu itp.). Więc napisałem to, aby odczytać z pliku XML i użyć refleksji Java, aby utworzyć instancję określonych klas i użyć metod ustawiających do ustawienia określonych parametrów.

Później przekonałem się, że Wiosna zrobi to samo dla ciebie i wiele więcej.

Więc w moim przypadku znalazłem to

  1. Korzystanie ze struktury wstrzykiwania zależności pomaga uelastycznić program i ułatwia określenie sposobu jego działania (oczywiście w ramach dobrze zdefiniowanych parametrów).

  2. Korzystanie z frameworku DI innej firmy pozwala uniknąć ponownego wymyślania koła.

Paul J Abernathy
źródło
4
Czy możesz wyjaśnić więcej, dlaczego określenie konkretnej klasy, która ma być używana, jest lepsze w pliku XML, a nie w pliku Java. Tego nigdy nie zrozumiałem.
Richard Tingle,
1
To nie jest magiczna kula, ale jedną z zalet korzystania z plików konfiguracyjnych jest to, że przynajmniej w teorii łatwiej je edytować niż kod. Ponadto mogą być zmieniane przez użytkownika, który uruchamia program, ale nie ma dostępu do kodu źródłowego. W podanym przeze mnie przykładzie mojego prostego programu do wstrzykiwania zależności czasami zmieniałem plik konfiguracyjny XML, abym mógł zmienić sposób działania programu, mimo że to ja go napisałem. Jeśli nie potrzebujesz zewnętrznej konfiguracji, łatwiej jest to zrobić za pomocą kodu. Miałem inną pracę, w której wykonaliśmy wszystkie DI w kodzie i to działało dobrze.
Paul J Abernathy,