Alternatywa dla kontenera DI

0

Cześć
Ostatnio czytam sobie rzeczy i spotkałem się z opinią, że kontener DI to ZUO. Załóżmy że chcę porzucić kontener, ale nie rezygnować z DI. Tylko jeśli nie kontener to co? Szukałem alternatywy jak używać z DI bez kontenera i niestety bez rezultatów. Gdzieś te instancje muszą zostać stworzone. Gdzie? Nie wyobrażam sobie klejenia wszystkiego ręcznie w Run'ie czy jak tam nazwiemy entry point. Z resztą (moim skromnym zdaniem) dalej jest to kontenerowe podejście - tylko zamiast używać framework'a to wykuwamy koło od nowa

Tak więc, czy macie jakąś sensowną alternatywę dla kontenera DI?

1

Nie wyobrażam sobie klejenia wszystkiego ręcznie w Run'ie czy jak tam nazwiemy entry point

Tak właśnie to wygląda bez kontenera ;-)
Przy czym jeśli wykorzystasz wzorzec fabryka, staje się to całkiem przyjemne w kodowaniu.

0

Nie wyobrażam sobie klejenia wszystkiego ręcznie w Run'ie czy jak tam nazwiemy entry point.

Nie musisz tworzyć wszystkiego w jednej metodzie. Możesz ją podzielić na klasy i metody. Jeśli jawna konstrukcja grafu zależności będzie mocno skomplikowana to najprawdopodobniej będzie to oznaczało iż aplikacja jest słabo zmodularyzowana (tzn jest zbyt dużo powiązań między odległymi klasami). Jakub Nabrdalik pokazuje na swoich prezentacjach modularyzację opartą o package scope w Javie. W takiej sytuacji wydaje mi się, że wstrzykiwanie zależności mogłoby odbywać się dwupoziomowo - każdy pakiet ma własną logikę do konstruowania hierarchii zależności z tego pakietu, a ponad tym jest jeszcze logika spinająca moduły (pakiety) do kupy.

0

Możesz podzielić projekt na moduły, gdzie każdy moduł tworzy się sam (na zasadzie, że tworzysz po prostu obiekt modułu, czy to jakimś obiektem z konfiguracji, czy czymś). Tak, nadal potrzebujesz jednego miejsca, żeby to spiąć do kupy przez co musisz zrobić to sam (rozwiązując od razu problemy z zależnościami. Przy okazji na pewno unikniesz cykli w zależnościach modułów). W zamian za to dostajesz pełną kontrole nad tym co, kiedy, gdzie i jak startuje.

0

@Tyvrel: To popatrz sobie jak działa Guice. I zasadniczo ręczne wstrzykiwanie zależności jest (w dużym uproszczeniu) prawdopodobnie bardzo podobe...

0

Jakoś się dało pisać te programy bez użycia kontenerów DI. Co do tego zła, to też można wybrać większe i mniejsze. Może popadam w paskudny relatywizm moralny, ale jednak czym innym jest taki Spring i jego "znajdź wszystkie beany implementujące jakiś tam interface i wstrzyknij jako listę bezpośrednio do pola prywatnego obiektu", a czym innym taki Dagger 2 z jego "napisz mi metody fabrykujące do wskazanych klas".

1

Odniose się do tego komentarza, bo mnie ciśnienie podnosi :-)

` Jakoś się dało pisać te programy bez użycia kontenerów1 DI dało sie też pisać w asemblerze, a potem bez bibliotek, a potem bez gotowych komponentów jak bazy danych czy kolejki... ;) Nadal się da! - Shalom 2018-12-06 09:27

To jest przykład tak zwanej fałszywej alternatywy. Można używać bibliotek. Można uzywać bardziej zwięzłych języków programowania, a nadal nie widzieć korzyści w kontenerowym DI.
Ja nie widze. To znaczy widzę trochę strat, które nie są rekompensowane przez potencjalne korzyści. Mam mniej więcej o kontenerowym DI takie zdanie jak o GOTO.
Jak weźmiesz bardzo mały lub specyficzny fragment kodu to pokażesz, że dzieki GOTO (Adnotacjom, DI) można coś zrobić szybciej. W średniej wielkości kodzie (więcej niż jeden CRUD :-) ) już różnica ilości kodu wychodzi praktycznie żadna, widzę za to bajzel jaki ta magia powoduje.

Mam nawet taką metrykę spustoszenia springowego/DI - klasa z największą ilością @Autowired/ Injectionów. 15tki-18tki to normalka.

Żeby nie było, kiedyś (na pewno jeszcze w 2013) kontenery, adnotacje mnie bardzo jarały i byłem praktykującym wyznawcą.

Najlepszy zresztą przykład, ze kontenery DI nie są potrzebne daje ... Spring. Nie znam kodu wszystkich modułów, ale te co trochę znam nie używają Springa(!), ani żadnego kontenerowego DI , mimo że mogłyby, bo od spring-core/spring-beans zależą :-). Przykład Spring-data-jpa, spring-tx. Może kod nie jest idealny, ale całkiem ładnie pokazuje jak fabryki rozwiazują problem.

2
jarekr000000 napisał(a):

Mam nawet taką metrykę spustoszenia springowego/DI - klasa z największą ilością @Autowired/ Injectionów. 15tki-18tki to normalka.

To mnie zawsze zastanawia. Czy jeżeli by zabrać możliwość ałtołajerowania, to czy ludzie by otrzeźwieli i pisaliby klasy bez przesadzania z zależnościami? Mam wrażenie, że konstruktor to taki bicz na lenistwo i gdyby wymusić korzystanie z niego dla zależności, to już łatwiej byłoby zorganizować odpowiednią strukturę klas. Z drugiej strony kontenery wcale nie przeszkadzają w rozsądnym pisaniu kodu (bardziej ułatwiają bylejakość) i kocham Daggera 2.

2

Wymuszenie ceremonii przepisywania argumentów z konstruktora do pól prywatnych pewnie mogłoby minimalnie poprawić sytuację, ale dalej magiczne wstrzykiwanie oznaczałoby, że nikt nie wiedziałby jak naprawdę wygląda graf zależności. Chociaż z drugiej strony jakieś narzędzia do wizualizacji grafu są, np: https://github.com/google/guice/wiki/Grapher Przy wielu klasach z kilkunastoma wstrzykniętymi parametrami taki graf zależności pewnie byłby nie do ogarnięcia przez zwykłego śmiertelnika.

1
jarekr000000 napisał(a):

To jest przykład tak zwanej fałszywej alternatywy. Można używać bibliotek. Można uzywać bardziej zwięzłych języków programowania, a nadal nie widzieć korzyści w kontenerowym DI.
Ja nie widze. To znaczy widzę trochę strat, które nie są rekompensowane przez potensjalne korzyści. Mam mniej więcej o kontenerowym DI takie zdanie jak o GOTO.
Jak weźmiesz bardzo mały lub specyficzny fragment kodu to pokażesz, że dzieki GOTO (Adnotacjom, DI) można coś zrobić szybciej. W średniej wielkości kodzie (więcej niż jeden CRUD :-) ) już różnica ilości kodu wychodzi praktycznie żadna, widzę za to bajzel jaki magia powoduje.

Mam nawet taką metrykę spustoszenia springowego/DI - klasa z największą ilością @Autowired/ Injectionów. 15tki-18tki to normalka.

Nikt nie każe wstawiać zależności przez @Autowired na polach. Jest kolosalna różnica pomiędzy dynamic proxy ze Springa i wstrzykiwaniem zależności refleksjami do klasy, a automatycznym tworzeniem fabryk przez takiego Daggera 2. Warto pamiętać, że te biblioteki / frameworki nikogo nie zmuszają to pisania kiepskiego kodu. Jak ktoś walnął klasę z 20 zależnościami to problemem jest głupota programisty a nie DI. Chociaż oczywiście Spring potrafi czasami zamaskować partactwo.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0