Czy ramy wstrzykiwania zależności stanowią ryzyko zależności?

13

Refaktoryzowałem istniejący system, aby używać wstrzykiwania zależności, a ta praca przebiega sprawnie.

Po jakimś czasie zauważyłem, że duża liczba bibliotek wewnętrznych stała się zależna od używanego przeze mnie środowiska DI. W rezultacie cały projekt zależy teraz od tego frameworka innej firmy.

Widziałem ironię w rozdzielaniu wszystkich zależności, uzależniając je od wspólnej biblioteki.

Pierwszą moją reakcją było stworzenie biblioteki otoki wokół struktury zależności. Dlatego w razie potrzeby mógłbym zastąpić te ramy. Po oszacowaniu zaangażowanej pracy zdałem sobie sprawę, że wynikowy interfejs API będzie podobny do istniejącego frameworka, a zatem utrudni to jego wymianę. Więc porzuciłem ten pomysł.

Obawiam się, że środowisko DI, z którego korzystam, staje się przestarzałe lub wymaga wymiany.

Czy podczas pracy z DI istnieje wzorzec programowania, który zmniejsza sprzężenie między projektem a ramą DI?

Reactgular
źródło
4
Wzorzec „nie używaj struktury DI”. Chociaż muszę się zastanawiać, czy rozwiązujesz problem, którego tak naprawdę nie masz - jak prawdopodobne jest, że zmienisz ramę DI?
Oded
1
@Oddany dobry framework DI powinien być w stanie pracować z kodem w sposób transparentny, ale są przypadki, w których nie jest to możliwe. Następnie musisz użyć interfejsów API DI w swoich klasach. W takich przypadkach trudno jest udostępnić lub zmienić framework DI bez konieczności zmiany tych klas. Ponieważ po raz pierwszy pracuję z tym frameworkiem DI. Nie jestem pewien, czy będę musiał go wymienić.
Reactgular
8
Twój system zależy również od prądu. Sugeruję, aby najpierw oddzielić.
Idan Arye
3
@MathewFoscarini Czy to nie jest anty-wzór? Możesz to zrobić, ale nie powinieneś, ponieważ zaciemnia to zależność.
maaartinus
2
@MathewFoscarini DIFramework.Get<IService>()nie jest tak naprawdę wstrzykiwaniem zależności; jest to powiązany wzorzec o nazwie Service Locator. Wiele osób nie lubi Lokalizatora usług, ponieważ łączy Cię on z frameworkiem i ponieważ jest zbyt łatwy do nadużywania (jak Singleton). Martin Fowler ma wspaniały artykuł o tych wzorach: martinfowler.com/articles/injection.html
Benjamin Hodgson

Odpowiedzi:

8

Masz całkowitą rację - użycie frameworka DI najprawdopodobniej uzależni Twój kod od tego. W rzeczywistości jest to zbyt zaskakujące, ponieważ jest to zwykle prawdziwe w przypadku każdej innej biblioteki frameworka lub biblioteki podstawowej, szczególnie gdy ta biblioteka obsługuje projekt z pewnymi ogólnymi funkcjami używanymi gdziekolwiek w kodzie. Na przykład, gdy zdecydujesz się użyć określonego frameworku interfejsu użytkownika lub frameworka WWW, decyzję tę trudno zmienić później, gdy tylko zbudujesz pewną ilość kodu na podstawie tej biblioteki. Jeśli zdecydujesz się użyć określonej (być może niestandardowej) Stringklasy, nie możesz później łatwo zmienić tej decyzji. Taka decyzja ma charakter architektoniczny, jest jak wybór określonego języka programowania i próba zmiany tej decyzji po napisaniu> 100 000 wierszy kodu.

Uzależnienie całego kodu od określonego frameworka może nie stanowić problemu, o ile robi to, czego się od niego oczekuje, i pod warunkiem, że jest odpowiednio utrzymywany. Ale może to stanowić problem, jeśli tak nie jest. Istnieje kilka strategii radzenia sobie z tą sytuacją:

  • wybierz platformę od dostawcy, któremu ufasz, że będzie on mógł dostarczać ci aktualizacje i nowe wersje za kilka lat

  • wybierz platformę open source, która ma wystarczającą liczbę wierszy kodu (i odpowiednią licencję), abyś mógł samodzielnie przeprowadzić dowolną konserwację, biorąc pod uwagę, że sprzedawca znika z rynku

  • napisz własne środowisko

  • żyj w sytuacji, dopóki sprzedawca jest dostępny, a kiedy naprawdę zniknie, wybierz inną platformę i spróbuj utworzyć adapter, który emuluje starą architekturę za pomocą nowej

Pomysł wcześniejszego utworzenia biblioteki opakowań nie jest wcale nowy, ale rzadko widziałem, że to działa, ponieważ musiałbyś przyjąć założenia dotyczące przyszłej sytuacji, w której nie wiesz, czy i kiedy cię uderzy, i co będą wyglądały „nowe” ramy. Z drugiej strony kilka lat temu z powodzeniem wymieniliśmy kompletną platformę interfejsu użytkownika w projekcie C ++ z ~ 120 000 linii kodu, stosując strategię adaptera, o której wspomniałem powyżej.

Doktor Brown
źródło
19

Zwykłe wstrzykiwanie konstruktora wcale nie wymaga szkieletu. Jedyną rzeczą, na której tracisz, jest możliwość scentralizowania zależności w pliku konfiguracyjnym.

Kontenery DI to wzorzec „oprogramowania korporacyjnego”, stosowany, gdy wykres obiektowy jest bardzo duży i złożony. Podejrzewam, że 95% aplikacji tego nie wymaga.

Robert Harvey
źródło
5
Zgadzam się, że małe projekty nie wymagają , ale 95 +% projektów mogą skorzystać z niego.
maaartinus
11
@maaartinus: Niepotrzebna dodatkowa złożoność dla minimalnych korzyści.
Robert Harvey
1
Co? Oto moje statystyki dla poszczególnych klas: adnotacja 0,5, linia konfiguracji 0,1. Więc jaką masz na myśli złożoność ???
maaartinus
2
@RobertHarvey: chociaż w 100% zgadzam się z powyższymi stwierdzeniami, OP stwierdza, że ​​już wprowadził framework DI. Powiedzenie mu „lepiej nie” nie jest tak naprawdę odpowiedzią na jego pytanie.
Doc Brown
1
@maaartinus im bardziej framework jest zautomatyzowany i im więcej rzeczy może wstrzyknąć, tym bardziej złożony. Istnieją pliki konfiguracyjne XML, wstrzykiwanie konstruktora, wstrzykiwanie właściwości, automatyczne mocking obiektów, leniwe wstrzykiwanie itd. Itd. Te frameworki DI mogą być bardzo złożone.
Reactgular
0

Nie sądzę, że frameworki DI mogą w najbliższym czasie stać się przestarzałe. Co powinno się stać, aby stało się przestarzałe?

  • Może wynalazek nowego i mądrzejszego wzoru? Jakkolwiek powinno to wyglądać, wymagałoby to znacznie większych zmian w kodzie.
  • Może zmiana języka? Nawet gorzej.

Powiedziałbym, że obecny DI jest wystarczająco dojrzały i nie jestem świadomy wielu wydarzeń. Nie określiłeś swojego języka, więc mówiąc o Guice , jest on dość nieprzeszkadzający i działa ze standardowymi adnotacjami w Javie (używa również własnego w przypadku rzeczy, które nie są znormalizowane, ale rzadko go potrzebujesz). Jest open source, szeroko stosowany i licencjonowany przez Apache. Co może być problemem?

Jestem prawie pewien, że zmiana frameworka DI byłaby o rząd wielkości łatwiejsza niż zmiana jakiejkolwiek innej biblioteki (np. Zmiana interfejsu użytkownika oznacza znacznie więcej pracy).

maaartinus
źródło