Wstrzykiwanie zależności: czy powinienem używać frameworka?

24

Niedawno pracowałem nad projektem Python, w którym intensywnie wykonaliśmy wstrzykiwanie zależności (ponieważ musimy, aby aplikacja była testowalna), ale nie użyliśmy żadnego frameworka. Czasami ręczne ułożenie wszystkich zależności było trochę uciążliwe, ale ogólnie działało świetnie.

Gdy obiekt musiał zostać utworzony w wielu miejscach, mieliśmy po prostu funkcję (czasem klasową metodę tego obiektu), aby utworzyć instancję produkcyjną. Ta funkcja była wywoływana za każdym razem, gdy potrzebowaliśmy tego obiektu.

W testach zrobiliśmy to samo: jeśli wiele razy musieliśmy stworzyć „wersję testową” obiektu (tj. Rzeczywistą instancję popartą próbnymi obiektami), mieliśmy funkcję do stworzenia tej „wersji testowej” klasy, do wykorzystania w testach.

Jak powiedziałem, ogólnie działało dobrze.

Wchodzę teraz w nowy projekt Java i decydujemy, czy użyć frameworka DI, czy wykonać DI ręcznie (jak w poprzednim projekcie).

Wyjaśnij, jak będzie wyglądała praca ze środowiskiem DI oraz w jaki sposób będzie on lepszy lub gorszy niż ręczne wstrzykiwanie zależności „waniliowej”.

Edycja: Chciałbym również dodać do pytania: czy widziałeś jakikolwiek projekt „profesjonalny”, który wykonuje DI ręcznie, bez ram?

Aviv Cohn
źródło
Obok mojej odpowiedzi. Oba sposoby są kompatybilne. Możesz pozostawić zastrzyk miękkiej zależności do frameworka i zachować swoje fabryki na kluczowe komponenty. Komponenty związane z modelem lub firmą.
Laiv
4
Wydaje mi się, że już sprawdziłeś, na wypadek, gdybyś nie. Dlaczego potrzebujemy ram dla DI?
Laiv

Odpowiedzi:

19

Kluczem do pojemników DI jest abstrakcja . Kontenery DI stanowią streszczenie tego problemu dla Ciebie. Jak można się domyślić, ma zauważalny wpływ na kod, często tłumaczony na mniejszą liczbę konstruktorów, seterów, fabryk i konstruktorów. W rezultacie sprawiają, że Twój kod jest luźniej sprzężony (z powodu IoC ), czystszy i prostszy. Chociaż nie bez kosztów.

Tła

Wiele lat temu taka abstrakcja wymagała od nas pisania różnych plików konfiguracyjnych ( programowanie deklaratywne ). Fantastycznie było widzieć, że liczba LOC znacznie się zmniejsza, ale chociaż LOCS spadły, liczba plików konfiguracyjnych nieznacznie wzrosła. W przypadku średnich i małych projektów wcale nie było problemu, ale w przypadku większych projektów rozproszenie „zestawu kodu” o 50% między kodem a deskryptorami XML stało się uciążliwe ... Niemniej jednak głównym problemem było sam paradygmat. Było dość mało elastyczne, ponieważ deskryptory pozostawiły niewiele miejsca na modyfikacje.

Paradygmat stopniowo przechodził w stronę konwencji nad konfiguracją , która wymienia pliki konfiguracyjne na adnotacje lub atrybuty. Utrzymuje nasz kod w czystości i prostocie, zapewniając jednocześnie elastyczność, której XML nie mógł.

Prawdopodobnie jest to najważniejsza różnica w stosunku do dotychczasowego sposobu pracy. Mniej kodu i więcej magii.

Z drugiej strony ...

Konwencja dotycząca konfiguracji sprawia, że ​​abstrakcja jest tak ciężka, że ​​ledwo wiesz, jak to działa. Czasami wydaje się magia i pojawia się jeszcze jedna wada. Kiedy już działa, wielu programistów nie dba o to, jak to działa.

Jest to utrudnienie dla tych, którzy nauczyli się DI z pojemnikami DI. Nie w pełni rozumieją znaczenie wzorców projektowych, dobrych praktyk i zasad wyodrębnionych przez kontener. Zapytałem programistów, czy są zaznajomieni z DI i jego zaletami i odpowiedzieli: - Tak, użyłem Spring IoC -. (Co do diabła to znaczy?!?)

Z każdą z tych „wad” można się zgodzić lub nie. Moim skromnym zdaniem trzeba wiedzieć, co dzieje się w twoim projekcie. W przeciwnym razie nie rozumiemy tego w pełni. Warto również wiedzieć, do czego służy DI i mieć pojęcie, jak ją wdrożyć.

Na plus...

Jedno słowo wydajność . Ramy pozwalają skupić się na tym, co naprawdę ważne. Biznes aplikacji.

Pomimo skomentowanych niedociągnięć, dla wielu z nas (których praca jest uwarunkowana terminami i kosztami) narzędzia te są nieocenionym zasobem. Moim zdaniem powinien to być nasz główny argument za wdrożeniem kontenerów DI. Produktywność .

Testowanie

Niezależnie od tego, czy wdrożymy czystą DI, czy kontenery, testowanie nie będzie stanowić problemu. Wręcz przeciwnie. Te same pojemniki często dostarczają nam próbnych testów jednostkowych po wyjęciu z pudełka. Przez lata korzystałem z moich testów jako termometrów. Mówią mi, czy w dużym stopniu polegałem na obiektach kontenerowych. Mówię to, ponieważ te kontenery mogą inicjować prywatne atrybuty bez ustawiaczy i konstruktorów. Mogą wstrzykiwać komponenty prawie w dowolnym miejscu!

Brzmi kusząco, prawda? Bądź ostrożny! Nie wpadnij w pułapkę !!

Propozycje

Jeśli zdecydujesz się na wdrożenie kontenerów, zdecydowanie zalecam stosowanie dobrych praktyk. Kontynuuj wdrażanie konstruktorów, ustawiaczy i interfejsów. Wymuszaj użycie frameworka / kontenera . Ułatwi to możliwe migracje do innego frameworka lub jego usunięcie. Może znacznie zmniejszyć zależność od kontenera.

W odniesieniu do tych praktyk:

Kiedy stosować pojemniki DI

Moja odpowiedź będzie stronnicza z własnego doświadczenia, które jest głównie na korzyść kontenerów DI (jak skomentowałem, jestem bardzo skoncentrowany na wydajności, więc nigdy nie potrzebowałem czystej DI. Wręcz przeciwnie).

Myślę, że znajdziesz interesujący artykuł Marka Seemana na ten temat, który również odpowiada na pytanie, jak wdrożyć czystą DI .

Na koniec, jeśli mówimy o Javie, rozważyłbym najpierw JSR330 - Dependency Injection .

Zreasumowanie

Korzyści :

  • Oszczędność kosztów i oszczędność czasu. Wydajność.
  • Mniejsza liczba komponentów.
  • Kod staje się prostszy i czystszy.

Wady :

  • DI jest delegowany do bibliotek stron trzecich. Powinniśmy zdawać sobie sprawę z ich kompromisów, mocnych i słabych stron.
  • Krzywa uczenia się.
  • Szybko sprawiają, że zapominasz o dobrych nawykach.
  • Zwiększenie zależności projektu (więcej bibliotek)
  • Kontenery oparte na odbiciu wymagają więcej zasobów (pamięci). Jest to ważne, jeśli ograniczają nas zasoby.

Różnice z czystym DI :

  • Mniej kodu i więcej plików konfiguracyjnych lub adnotacji.
Laiv
źródło
1
„Te frameworki nie są dla ciebie prywatne do przeprowadzania testów jednostkowych lub testów integralności, więc nie martw się o testowanie.” Co to dokładnie oznacza? Sformułowanie sprawia, że ​​myślę, że to literówka, ale mam problem z jej odkodowaniem.
candied_orange
Oznacza to, że trudne debugowanie lub użycie frameworków do testowania nie jest wystarczającą wadą, aby odrzucić użycie tych frameworków. Ponieważ nawet jeśli ich nie lubisz, wciąż mają korzyści, które naprawdę warto wypróbować. Dużymi wadami nie są same ramy. To jak ich używasz. Niektóre dobre praktyki, takie jak interfejsy i setery, są nadal wymagane, nawet jeśli twój framework nie. Wreszcie istnieją dobre biblioteki do testowania, które łatwo integrują się z tego rodzaju frameworkami (DI)
Laiv
Jeśli to masz na myśli, zastanów się: „Te frameworki nie przeszkadzają w przeprowadzaniu testów jednostkowych lub testów integralności, więc nie martw się, jak wpływają one na testowanie”
candied_orange
Srry. Próbuję powiedzieć, że będzie w stanie przetestować swój kod nawet przy użyciu tych frameworków. Pomimo abstrakcji testy są nadal wykonalne. Edytuj swoją odpowiedź. Jak widzisz, mój angielski jest wciąż daleko do przyzwoitości :-)
Laiv
1
Zauważ, że Dagger2 robi DI nieco inaczej. Kod kleju jest generowany w czasie kompilacji jako normalne, czytelne źródła Java, więc o wiele łatwiej jest śledzić, jak rzeczy są ze sobą sklejane, zamiast zajmować się magią środowiska uruchomieniowego.
Thorbjørn Ravn Andersen
10

Z mojego doświadczenia wynika, że ​​struktura wstrzykiwania zależności prowadzi do wielu problemów. Niektóre problemy będą zależeć od struktury i narzędzi. Mogą istnieć praktyki łagodzące problemy. Ale to są problemy, które dotknąłem.

Obiekty nieglobalne

W niektórych przypadkach chcesz wstrzyknąć obiekt globalny: obiekt, który będzie miał tylko jedną instancję w uruchomionej aplikacji. Może to być MarkdownToHtmlRendererer, A DatabaseConnectionPool, adres dla serwera API, itp dla tych przypadków, ramy wtrysku zależność działa w bardzo prosty sposób, wystarczy dodać potrzebne zależność do konstruktora i masz go.

Ale co z obiektami, które nie są globalne? Co jeśli potrzebujesz użytkownika do bieżącego żądania? Co jeśli potrzebujesz aktualnie aktywnej transakcji bazy danych? Co jeśli potrzebujesz elementu HTML odpowiadającego div, który zawiera formularz, w którym jest pole tekstowe, które właśnie uruchomiło zdarzenie?

Rozwiązaniem, które widziałem stosowane przez frameworki DI, są hierarchiczne wtryskiwacze. Ale to czyni model wtrysku bardziej skomplikowanym. Trudniej jest ustalić, co zostanie wstrzyknięte z jakiej warstwy hierarchii. Trudno powiedzieć, czy dany obiekt będzie istniał dla aplikacji, użytkownika, żądania itp. Nie można już tylko dodawać swoich zależności i sprawić, by działały.

Biblioteki

Często będziesz chciał mieć bibliotekę kodu wielokrotnego użytku. Obejmuje to również instrukcje dotyczące konstruowania obiektów z tego kodu. Jeśli używasz struktury wstrzykiwania zależności, zwykle będzie to obejmować reguły wiązania. Jeśli chcesz korzystać z biblioteki, dodajesz do niej wiążące reguły.

Mogą jednak wystąpić różne problemy. Możesz skończyć z tą samą klasą związaną z różnymi implementacjami. Biblioteka może oczekiwać pewnych powiązań. Biblioteka może zastąpić niektóre domyślne wiązania, powodując dziwne działania kodu. Twój kod może zastąpić niektóre domyślne wiązania, powodując dziwne rzeczy w kodzie biblioteki.

Ukryta złożoność

Podczas ręcznego pisania fabryk masz poczucie, w jaki sposób pasują do siebie zależności aplikacji. Kiedy używasz struktury wstrzykiwania zależności, nie widzisz tego. Zamiast tego obiekty mają coraz więcej zależności, aż prędzej czy później wszystko zależy od prawie wszystkiego.

Obsługa IDE

Twoje IDE prawdopodobnie nie zrozumie struktury wstrzykiwania zależności. Dzięki ręcznym fabrykom możesz znaleźć wszystkie obiekty wywołujące konstruktora, aby dowiedzieć się o wszystkich miejscach, w których obiekt może zostać zbudowany. Ale nie znajdzie połączeń generowanych przez środowisko DI.

Wniosek

Co otrzymujemy ze struktury wstrzykiwania zależności? Unikamy prostackiej płyty potrzebnej do tworzenia obiektów. Jestem za eliminacją prostych pomysłów. Jednak utrzymanie prostej płyty kotłowej jest łatwe. Jeśli zamierzamy wymienić płytę kotła, powinniśmy nalegać na zastąpienie jej czymś łatwiejszym. Z powodu różnych zagadnień, które omówiłem powyżej, nie sądzę, aby ramy (przynajmniej takie, jakie stoją) pasowały do ​​rachunku.

Winston Ewert
źródło
To bardzo dobra odpowiedź, ale nie wyobrażam sobie używania kontenera IoC do biblioteki klas. To wydaje mi się kiepskim projektem. Oczekiwałbym, że biblioteka wyraźnie da mi wszelkie zależności, których wymaga.
RubberDuck
@RubberDuck, w moim przypadku, pracowałem dla dużej firmy z dużą liczbą projektów Java, wszystkie standaryzowane na tej samej platformie wstrzykiwania zależności. W tym momencie kusi niektóre zespoły, aby wyeksportować bibliotekę, która spodziewa się zostać złożona przez środowisko DI, zamiast zapewniać sensowny interfejs zewnętrzny.
Winston Ewert
To niefortunne @WinstonEwert. Dziękuję za wypełnienie kontekstu dla mnie.
RubberDuck
Byłoby wspaniale części IDE, z wiązaniem środowiska wykonawczego wstrzyknięć w przeciwieństwie do wiązania typu ręcznego wstrzykiwania w czasie. Kompilator zapobiega zapomnianym zastrzykom, gdy są wykonywane ręcznie.
Basilevs,
IntelliJ rozumie CDI (standard Java EE DI)
Thorbjørn Ravn Andersen
3

Czy wymagane jest wstrzykiwanie zależności Java = framework?

Nie.

Co kupuje środowisko DI?

Konstrukcja obiektu odbywa się w języku innym niż Java.


Jeśli metody fabryczne są wystarczająco dobre dla twoich potrzeb, możesz wykonać DI w java całkowicie za darmo w 100% autentyczne pojo java. Jeśli twoje potrzeby wykraczają poza to, masz inne opcje.

Wzory projektowe Gang of Four pozwalają osiągnąć wiele wspaniałych rzeczy, ale zawsze były słabe, jeśli chodzi o wzory kreacyjne. Sama Java ma tutaj pewne słabości. Frameworki DI naprawdę pomagają w tej słabości twórczej bardziej niż w przypadku rzeczywistych zastrzyków. Wiesz już, jak to zrobić bez nich. Ile dobrego ci zrobią, zależy od tego, ile pomocy potrzebujesz przy budowie obiektów.

Istnieje wiele wzorców twórczych, które pojawiły się po Gangu Czterech. Konstruktor Josh Bloch to wspaniały hack wokół braku nazwanych parametrów Java. Poza tym są konstruktory iDSL, które oferują dużą elastyczność. Ale każdy z nich reprezentuje znaczną pracę i płytę kotłową.

Ramy mogą cię uratować przed niektórymi z tego nudy. Nie są pozbawione wad. Jeśli nie jesteś ostrożny, możesz stać się zależny od frameworka. Spróbuj zmienić ramy po użyciu jednego i przekonaj się sam. Nawet jeśli w jakiś sposób utrzymujesz ogólny kod XML lub adnotacje, możesz w końcu obsługiwać zasadniczo dwa języki, o których musisz wspominać obok siebie, gdy reklamujesz zadania programistyczne.

Zanim zaczniesz się zbytnio zakochać w potędze frameworków DI, poświęć trochę czasu i zbadaj inne frameworki, które dadzą ci możliwości, które w innym przypadku mogą ci się wydawać potrzebne. Wiele z nich wykracza poza proste DI . Zastanów się: Lombok , AspectJ i slf4J . Każda nakłada się na niektóre frameworki DI, ale każda z nich działa dobrze samodzielnie.

Jeśli testowanie jest naprawdę siłą napędową tego, proszę spojrzeć na: jUnit (naprawdę xUnit) i Mockito (jakikolwiek mock naprawdę), zanim zaczniesz myśleć, że środowisko DI powinno przejąć twoje życie.

Możesz robić, co chcesz, ale do poważnej pracy wolę dobrze wypełnioną skrzynkę narzędziową niż szwajcarski scyzoryk. Szkoda, że ​​nie było łatwiej narysować tych linii, ale niektórzy ciężko pracowali, aby je zatrzeć. Nie ma w tym nic złego, ale może to utrudnić wybór.

CandiedOrange
źródło
PowerMock rozwiązał niektóre z tych przypadków. Atleast to pozwalają makiety statykę
LAIV
Meh Jeśli robisz DI poprawnie, wymiana jednej struktury kontenera IoC na inną powinna być stosunkowo prosta. Trzymaj te adnotacje poza kodem, a wszystko będzie dobrze. Zasadniczo użyj kontenera IoC do wykonania DI zamiast używania kontenera jako lokalizatora usług.
RubberDuck
@ RubberDuck poprawnie. Czy brakuje Ci ciągłego testowania i utrzymywania bazy kodu w wielu ramach DI? Czy znasz prosty, niezawodny sposób na sprawdzenie, czy „poprawnie wykonujesz DI”? Nawet jeśli używam tylko java w języku java, jeśli włożony został znaczny wysiłek w tworzenie XML, nadal nie jest to prosta zamiana, gdy XML jest zależny od kontenera IoC.
candied_orange
@CandiedOrange Używam „prostego” jako terminu względnego. W wielkim schemacie rzeczy zastąpienie jednego rdzenia kompozycji innym nie jest zbyt trudnym zadaniem. Kilkudniowe blaty robocze. Jeśli chodzi o upewnienie się, że robisz DI prawidłowo, właśnie po to są recenzje kodowe.
RubberDuck
2
@ RubberDuck większość „korzeni kompozycji”, jakie widziałem, zawiera około 5 linii kodu. Więc nie. niezbyt trudne zadanie. To zastrzeżony materiał, który wymyka się liniom, przed którymi ostrzegam. Nazywacie to „prawidłowym wykonywaniem DI”. Pytam, czy możesz użyć tego, aby udowodnić problem podczas przeglądu kodu. A może po prostu powiesz „Meh”?
candied_orange
2

Tworzenie klas i przypisywanie im zależności jest częścią procesu modelowania, zabawnymi częściami. To jest powód, dla którego większość programistów lubi programować.

Decyzja o tym, która implementacja zostanie użyta i jak skonstruowane są klasy, należy w jakiś sposób zaimplementować i jest częścią konfiguracji aplikacji.

Ręczne pisanie fabryk to żmudne dzieło. Frameworki DI ułatwiają automatyczne rozwiązywanie zależności, które mogą zostać rozwiązane, i wymagają konfiguracji dla tych, które mogą nie.

Korzystanie z nowoczesnych IDE umożliwia nawigację między metodami i ich zastosowaniami. Ręczne pisanie fabryk jest całkiem dobre, ponieważ możesz po prostu wyróżnić konstruktora klasy, pokazać jego zastosowania, a pokaże Ci wszystkie miejsca, w których i jak budowana jest dana klasa.

Ale nawet w środowisku DI możesz mieć centralne miejsce, takie jak konfiguracja konstrukcji wykresów obiektowych (od tej pory OGCC), a jeśli klasa zależy od niejednoznacznych zależności, możesz po prostu zajrzeć do OGCC i zobaczyć, jak budowana jest konkretna klasa tam.

Możesz sprzeciwić się, że osobiście uważasz, że możliwość korzystania z określonego konstruktora to świetny plus. Powiedziałbym, że to, co wychodzi ci lepiej, jest nie tylko subiektywne, ale przede wszystkim pochodzi z osobistego doświadczenia.

Gdybyś zawsze pracował nad projektami opartymi na frameworkach DI, tak naprawdę wiedziałbyś tylko to, a kiedy chciałeś zobaczyć konfigurację klasy, zawsze patrzyłbyś na OGCC i nawet nie próbowałbyś zobaczyć, jak używane są konstruktory , ponieważ wiedziałbyś, że wszystkie zależności i tak są podłączone automatycznie.

Oczywiście frameworki DI nie mogą być używane do wszystkiego i co jakiś czas będziesz musiał napisać metodę fabryczną. Bardzo częstym przypadkiem jest konstruowanie zależności podczas iteracji nad kolekcją, gdzie każda iteracja dostarcza inną flagę, która powinna wytworzyć inną implementację inaczej wspólnego interfejsu.

Ostatecznie najprawdopodobniej wszystko sprowadzi się do twoich preferencji i tego, co chcesz poświęcić (czas pisania fabryk lub przejrzystość).


Osobiste doświadczenie (ostrzeżenie: subiektywne)

Mówiąc jako programista PHP, chociaż podoba mi się pomysł na frameworki DI, użyłem ich tylko raz. Wtedy zespół, z którym pracowałem, miał bardzo szybko wdrożyć aplikację i nie mogliśmy stracić czasu na pisanie fabryk. Więc po prostu wybraliśmy framework DI, skonfigurowaliśmy go i jakoś zadziałał .

W przypadku większości projektów lubię ręcznie pisać fabryki, ponieważ nie podoba mi się czarna magia zachodząca w ramach DI. Byłem odpowiedzialny za modelowanie klasy i jej zależności. To ja decydowałem, dlaczego projekt wygląda tak, jak wygląda. Będę więc tym, który poprawnie konstruuje klasę (nawet jeśli klasa przyjmuje twarde zależności, takie jak konkretne klasy zamiast interfejsów).

Andy
źródło
2

Osobiście nie używam pojemników DI i nie lubię ich. Mam na to jeszcze kilka powodów.

Zwykle jest to zależność statyczna. Jest to więc tylko lokalizator usług ze wszystkimi jego wadami. Następnie, ze względu na charakter zależności statycznych, są one ukryte. Nie musisz sobie z nimi radzić, oni już tam są i jest to niebezpieczne, ponieważ przestajesz je kontrolować.

To łamie zasady OOP , takie jak spójność i David West „s Lego cegły obiektu metafory.

Tak więc budowanie całego obiektu jak najbliżej punktu wejścia programu jest dobrym rozwiązaniem.


źródło
1

Jak już zauważyłeś: w zależności od używanego języka istnieją różne punkty widzenia, różni się, jak radzić sobie z podobnymi problemami.

W odniesieniu do wstrzykiwania zależności sprowadza się to do tego: wstrzykiwanie zależności jest, jak to się mówi, niczym więcej niż umieszczeniem zależności, których jeden obiekt potrzebuje w tym obiekcie - w przeciwieństwie do drugiej strony: pozwalanie, aby sam obiekt inicjował instancje obiektów, od których zależy. Oddzielasz tworzenie i zużycie obiektu, aby uzyskać większą elastyczność.

Jeśli twój projekt jest dobrze rozplanowany, zwykle masz kilka klas z wieloma zależnościami, dlatego zestawianie zależności - ręcznie lub za pomocą szkieletu - powinno być względnie łatwe, a ilość planszy do napisania testów powinna być łatwa do zarządzania.

To powiedziawszy, nie ma potrzeby tworzenia ram DI.

Ale dlaczego mimo wszystko chcesz używać frameworka?

I) Unikaj kodu płyty kotłowej

Jeśli twój projekt nabiera rozmiarów, w którym ciągle odczuwasz ból związany z pisaniem fabryk (i instatacji), powinieneś użyć struktury DI

II) Deklaracyjne podejście do programowania

Kiedy Java programowała kiedyś za pomocą XML , teraz jest: posypywanie bajki adnotacjami i magia się dzieje .

Ale poważnie: widzę wyraźną zaletę tego. Wyraźnie komunikujesz zamiar powiedzenia, co jest potrzebne zamiast tego, gdzie to znaleźć i jak to zbudować.


tl; dr

Frameworki DI nie poprawiają magicznie bazy kodu, ale pomagają sprawić, że dobrze wyglądający kod wygląda naprawdę ostro . Użyj go, kiedy czujesz, że go potrzebujesz. W pewnym momencie projektu zaoszczędzisz czas i zapobiegniesz mdłościom.

Thomas Junk
źródło
1
Masz rację! Zbyt często martwię się o to, jak wszystko działa pod maską. Miałem okropne doświadczenia w pracy z frameworkami, które ledwo rozumiałem. Nie opowiadam się za testowaniem frameworków, po prostu zrozum, co robią i jak to robią (jeśli to możliwe). Ale to zależy od twoich zainteresowań. Myślę, że rozumiejąc, jak one działają, możesz lepiej zdecydować, czy są odpowiednie dla Ciebie. Na przykład w ten sam sposób, w jaki porównywałbyś różne ORM.
Laiv
1
Myślę, że zawsze dobrze jest wiedzieć, jak rzeczy działają pod maską. Ale to nie powinno dziwić, że nie wiesz. Myślę, że zaletą Spring jest na przykład to, że po prostu działa. I tak, masz absolutną rację, że aby podjąć świadomą decyzję o korzystaniu z ram, musisz mieć pewien stopień wiedzy. Ale zbyt często widzę wzór nieufności dla ludzi, którzy nie mają takich samych blizn jak on sam, chociaż nie w twoim przypadku, gdzie istnieje przekonanie, tylko ten, który doświadczył ręcznego polowania, może udać się do supermarketu.
Thomas Junk
Na szczęście w dzisiejszych czasach nie potrzebujemy nawet frameworków Spring ani DI dla Java. Mamy już JSR330, który jest niestety ignorowany (przynajmniej nie widziałem projektu, który go wdraża). Tak więc ludzie wciąż mają czas, aby wygrać blizny :-)
Laiv
Zredagowałem swoją odpowiedź i wziąłem pod uwagę twoje komentarze. Usunąłem „wady” związane z debugowaniem. Doszedłem do wniosku, że masz rację. Spójrz i rozważ zaktualizowanie swojej odpowiedzi, ponieważ w tej chwili cytowałbyś części, które usunąłem z mojej odpowiedzi.
Laiv
1
Odpowiedź zmieniła się tak mało !!! Nic, co nie powinno Cię martwić :-). Wiadomość i argumenty pozostają takie same. Chciałem tylko, żeby twoja odpowiedź była taka, jaka jest. Chyba zajęło ci to usunięcie jednego z cytatów.
Laiv
0

Tak. Prawdopodobnie powinieneś przeczytać książkę Marka Seemanna zatytułowaną „Dependency Injection”. Przedstawia kilka dobrych praktyk. W zależności od tego, co powiedziałeś, możesz skorzystać. Powinieneś dążyć do posiadania jednego katalogu głównego kompozycji lub jednego katalogu głównego kompozycji na jednostkę pracy (np. Żądanie sieciowe). Podoba mi się jego sposób myślenia, że ​​każdy obiekt, który tworzysz, jest uważany za zależność (podobnie jak każdy parametr metody / konstruktora), więc powinieneś naprawdę uważać na to, gdzie i jak tworzysz obiekty. Ramy pomogą ci wyjaśnić te pojęcia. Jeśli czytasz książkę Marka, znajdziesz więcej niż odpowiedź na swoje pytanie.

Keith
źródło
0

Tak, podczas pracy w Javie polecam framework DI. Jest kilka powodów:

  • Java ma kilka bardzo dobrych pakietów DI, które oferują automatyczne wstrzykiwanie zależności, a także zwykle są dostarczane z dodatkowymi funkcjami, które trudniej jest napisać ręcznie niż proste DI (np. Zależności zakresowe, które umożliwiają automatyczne połączenie między zakresami poprzez generowanie kodu w celu sprawdzenia, jaki zakres powinien być użyj d, aby znaleźć poprawną wersję zależności dla tego zakresu - na przykład obiekty o zasięgu aplikacji mogą odnosić się do obiektów o zasięgu na żądanie).

  • Adnotacje Java są niezwykle przydatne i zapewniają doskonały sposób konfigurowania zależności

  • Konstrukcja obiektu Java jest zbyt wyczerpująca w porównaniu do tego, do czego jesteś przyzwyczajony w Pythonie; użycie tu frameworka oszczędza więcej pracy niż w dynamicznym języku.

  • Frameworki Java java mogą robić użyteczne rzeczy, takie jak automatyczne generowanie serwerów proxy i dekoratorów, które działają więcej w Javie niż w języku dynamicznym.

Jules
źródło
0

Jeśli twój projekt jest wystarczająco mały i nie masz dużego doświadczenia z DI-Framework, odradzam korzystanie z niego i zrobienie tego ręcznie.

Powód: Kiedyś pracowałem nad projektem, który wykorzystywał dwie biblioteki, które miały bezpośrednie zależności od różnych struktur. oba miały kod specyficzny dla frameworka, taki jak di-give-me-an-instance-of-XYZ. O ile wiem, możesz mieć tylko jedną aktywną implementację di-framework na raz.

z takim kodem możesz wyrządzić więcej szkody niż korzyści.

Jeśli masz więcej doświadczenia, prawdopodobnie pozbyłbyś się diamontażu za pomocą interfejsu (fabryka lub servicelocator), więc ten problem już nie będzie istniał, a di di framewor przyniesie więcej korzyści tej szkodzie.

k3b
źródło