Rozumiem korzyści płynące z samego wstrzyknięcia zależności. Weźmy na przykład wiosnę. Rozumiem również zalety innych funkcji Springa, takich jak AOP, pomocników różnego rodzaju itp. Zastanawiam się tylko, jakie są zalety konfiguracji XML, takich jak:
<bean id="Mary" class="foo.bar.Female">
<property name="age" value="23"/>
</bean>
<bean id="John" class="foo.bar.Male">
<property name="girlfriend" ref="Mary"/>
</bean>
w porównaniu ze zwykłym starym kodem java, takim jak:
Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);
który jest łatwiejszy do debugowania, sprawdzania czasu kompilacji i może być zrozumiany przez każdego, kto zna tylko java. Więc jaki jest główny cel struktury wstrzykiwania zależności? (lub fragment kodu, który pokazuje jego zalety).
UPDATE: w
przypadku
IService myService;// ...
public void doSomething() {
myService.fetchData();
}
W jaki sposób framework IoC może odgadnąć, którą implementację myService chcę wprowadzić, jeśli jest więcej niż jedna? Jeśli istnieje tylko jedna implementacja danego interfejsu, a ja pozwolę kontenerowi IoC automatycznie zdecydować się na jej użycie, to po pojawieniu się drugiej implementacji zostanie zerwany. A jeśli celowo istnieje tylko jedna możliwa implementacja interfejsu, nie musisz jej wstrzykiwać.
Byłoby naprawdę interesujące zobaczyć mały fragment konfiguracji IoC, który pokazuje jego zalety. Spring używam od jakiegoś czasu i nie mogę podać takiego przykładu. Mogę pokazać pojedyncze linie, które pokazują zalety hibernacji, dwr i innych frameworków, których używam.
UPDATE 2:
Zdaję sobie sprawę, że konfigurację IoC można zmienić bez ponownej kompilacji. Czy to naprawdę dobry pomysł? Rozumiem, kiedy ktoś chce zmienić poświadczenia bazy danych bez ponownej kompilacji - może nie być programistą. W twojej praktyce, jak często ktoś inny niż programista zmienia konfigurację IoC? Myślę, że dla programistów nie ma żadnego wysiłku, aby przekompilować tę konkretną klasę zamiast zmieniać konfigurację. A dla osób niebędących programistami prawdopodobnie chciałbyś ułatwić mu życie i zapewnić prostszy plik konfiguracyjny.
AKTUALIZACJA 3:
Zewnętrzna konfiguracja mapowania między interfejsami i ich konkretnymi implementacjami
Co jest takiego dobrego w uczynieniu go ekstensywnym? Nie możesz uczynić całego kodu zewnętrznymi, chociaż zdecydowanie możesz - po prostu umieść go w pliku ClassName.java.txt, czytaj i kompiluj ręcznie w locie - wow, uniknąłeś ponownej kompilacji. Dlaczego należy unikać kompilacji ?!
Oszczędzasz czas potrzebny na kodowanie, ponieważ odwzorowania podajesz deklaratywnie, a nie w kodzie proceduralnym
Rozumiem, że czasami deklaratywne podejście oszczędza czas. Na przykład deklaruję tylko raz mapowanie między właściwością bean a kolumną DB, a hibernacja używa tego mapowania podczas ładowania, zapisywania, budowania SQL w oparciu o HSQL itp. W tym miejscu działa podejście deklaratywne. W przypadku Springa (w moim przykładzie) deklaracja miała więcej linii i miała taką samą wyrazistość jak odpowiadający jej kod. Jeśli jest przykład, kiedy taka deklaracja jest krótsza niż kod - chciałbym to zobaczyć.
Zasada odwrócenia kontroli pozwala na łatwe testowanie jednostkowe, ponieważ można zastąpić rzeczywiste implementacje fałszywymi (np. Zastąpienie bazy danych SQL bazą danych w pamięci)
Rozumiem odwrócenie korzyści ze sterowania (wolę nazywać omawiany tu wzorzec projektowy jako Dependency Injection, ponieważ IoC jest bardziej ogólny - jest wiele rodzajów kontroli, a odwracamy tylko jeden z nich - sterowanie inicjalizacją). Pytałem, dlaczego ktoś potrzebuje do tego czegoś innego niż język programowania. Zdecydowanie mogę zamienić prawdziwe implementacje na fałszywe z użyciem kodu. Ten kod będzie wyrażał to samo co konfiguracja - po prostu zainicjuje pola z fałszywymi wartościami.
mary = new FakeFemale();
Rozumiem korzyści płynące z DI. Nie rozumiem, jakie korzyści daje zewnętrzna konfiguracja XML w porównaniu z konfiguracją kodu, który robi to samo. Nie uważam, że należy unikać kompilacji - kompiluję codziennie i wciąż żyję. Myślę, że konfiguracja DI jest złym przykładem podejścia deklaratywnego. Deklaracja może być przydatna, jeśli jest zadeklarowana raz ORAZ jest używana wiele razy na różne sposoby - jak hibernacja cfg, gdzie mapowanie między właściwością fasoli a kolumną DB jest używane do zapisywania, ładowania, budowania zapytań wyszukiwania itp. Konfigurację Spring DI można łatwo przetłumaczyć na konfigurowanie kodu, jak na początku tego pytania, czyż nie? I jest używany tylko do inicjalizacji fasoli, prawda? Co oznacza, że podejście deklaratywne niczego tutaj nie dodaje, prawda?
Kiedy deklaruję mapowanie hibernacji, po prostu podaję informacje o hibernacji i działa na tej podstawie - nie mówię mu, co ma robić. W przypadku wiosny moja deklaracja mówi wiosnie dokładnie, co ma robić - więc po co to deklarować, dlaczego po prostu tego nie robić?
OSTATNIA AKTUALIZACJA:
Chłopaki, wiele odpowiedzi mówi mi o zastrzyku zależności, o którym WIEM, że JEST DOBRY. Pytanie dotyczy celu konfiguracji DI zamiast inicjalizacji kodu - wydaje mi się, że kod inicjujący jest krótszy i bardziej przejrzysty. Jedyną odpowiedzią, jaką uzyskałem do tej pory na moje pytanie, jest to, że unika się ponownej kompilacji, gdy zmienia się konfiguracja. Chyba powinienem zadać kolejne pytanie, bo to dla mnie wielka tajemnica, dlaczego w tym przypadku należy unikać kompilacji.