W jaki sposób wtrysk zależny zwiększa sprzęganie?


32

Na stronie Wikipedii dotyczącej wstrzykiwania zależności, sekcja wad mówi:

Wstrzykiwanie zależności zwiększa sprzężenie, wymagając od użytkownika podsystemu zaspokojenia potrzeb tego podsystemu.

z linkiem do artykułu przeciw wstrzykiwaniu zależności .

Wstrzykiwanie zależności powoduje, że klasa korzysta z interfejsu zamiast konkretnej implementacji. To powinno skutkować zmniejszeniem sprzężenia , prawda?

czego mi brakuje? W jaki sposób wstrzykiwanie zależności zwiększa sprzężenie między klasami?


2
Nie jestem pewien, kto napisał tę listę wad, ale wziąłbym ją z odrobiną soli. Na przykład widziałem, że DI zmniejsza rozmiar podstawy kodu o 2/3, eliminując tonę zbędnego kodu konfiguracji.
— Rob

@RobY Najczęściej używałem fabryki do wstrzykiwania zależności, a moim doświadczeniem jest to, że zwiększa rozmiar kodu, ale upraszcza testowanie.
— BЈовић

Spróbuj użyć alternatywy, takiej jak rejestr lub przekazywanie kontekstu;) Albo kod, który tworzy instancję obiektów, a następnie pobiera ich właściwości z config. Głównie mówię o różnicy między teraz a 15 lat temu.
— Rob

Powiązane: stackoverflow.com/a/9503612/264697 . Odpowiedź Marka Seemanna wyjaśnia, w jaki sposób ogólne sprzężenie jest zmniejszane przy użyciu wstrzykiwania zależności.
— Steven

Odpowiedzi:


42

Więc czego mi brakuje?

Wstrzykiwanie zależności zmniejsza sprzężenie między klasą i jej zależnością. Ale zwiększa to sprzężenie między klasą a jej konsumentem (ponieważ konsument potrzebuje więcej informacji, aby ją utworzyć) oraz zależnością i jej konsumentem (ponieważ konsument musi znać zależność, której należy użyć).

Bardzo często jest to dobry kompromis. Klasa nie powinna znać szczegółów na temat swoich zależności poza interfejsem, a na aplikacji powinna spoczywać powiązanie określonych fragmentów kodu.


Racja, sprzężenie zmniejsza się w jedną stronę, a zwiększa w drugą.
— Paul Draper

Ale konsument go nie tworzy; o to właśnie chodzi.
— Casey

@emodendroket - Eh? Odwrócenie kontroli pozwala konsumentowi go nie tworzyć. Wstrzykiwanie zależności jest prostopadłe do tego.
— Telastyn

Robisz rozróżnienie, którego nie znam, ponieważ zwykle terminy są używane zamiennie.
— Casey

22

Załóżmy, że masz podsystem Szależny od połączenia z bazą danych D. Bez wstrzykiwania zależności istnieje względnie ścisłe sprzężenie między Si D, ponieważ Smusi wiedzieć zarówno, jak używać, Djak i jak go tworzyć. Reszta systemu może jednak być błogo nieświadoma tej zależności między Si D.

W przypadku wstrzykiwania zależności sprzężenie Si Dstaje się luźniejsze, ponieważ usuwasz z Swiedzy, jak utworzyć D. Spo prostu musi wiedzieć, jak go używać. Zwiększone ogólne sprzężenie wynika z faktu, że inne części systemu muszą teraz wiedzieć Di być może jak je utworzyć. Zakres tego wzrostu sprzężenia zależy od tego, w jaki sposób Dwstrzykiwana jest zależność od S:

  • Dzięki iniekcji konstruktora twórca Spotrzebuje zależności Di być może wiedzy, jak ją stworzyć.
  • W przypadku wstrzykiwania na poziomie metody każdy wywołujący metodę, za Spomocą której Dwstrzykiwany jest zastrzyk, potrzebuje zależności Di być może wiedzy, jak go stworzyć.

W obu przypadkach liczba klas, które zależą od Dwzrostu, i wiedza na temat tworzenia Dwciąż musi znajdować się gdzieś w systemie. To powoduje ogólny wzrost sprzężenia.


Ok, ma sens zastrzyk konstruktora i setera. Ale jeśli używa się wzorca fabrycznego lub strategicznego, kreacja jest tam przenoszona, a klasa używa tylko wstrzykiwanego obiektu. Czy też nie jest to wstrzyknięcie zależności (tylko odwrócenie kontroli)?
— BЈовић

Nawet w przypadku wstrzyknięcia fabrycznego twórca Smusi dostarczyć fabrykę D, co oznacza, że ​​musi wiedzieć, które Szastosowania D(lub przynajmniej pewien jej interfejs).
— Idan Arye

7

Zdecydowanie nie zgadzam się, że zwiększa to sprzężenie.

Bez wstrzykiwania zależności masz ścisłe połączenie między podsystemem a konkretną implementacją zależności.

Po wstrzyknięciu zależności odłączyłeś podsystem od implementacji zależności.

Argumentowanie, że zwiększa sprzężenie między konsumentem a tym podsystemem, jest BARDZO wątpliwe, ponieważ sugeruje, że konsument jest teraz ściśle powiązany z zależnością wymaganą przez podsystem. Oznacza to tylko, że piszesz ściśle powiązany kod, który łączy klienta z zależnością. Idealnie WSZYSTKO twój kod jest oddzielony.

Wtrysk Konstruktora:

Rozdzielczość zależności jest obsługiwana przez pojemnik wstrzykiwania zależności lub fabrykę. Konsument może uzyskać konkretną implementację podsystemu z pojemnika wstrzykiwania zależności lub z fabryki.

Konsument nie musi wiedzieć, jak wygląda konstruktor podsystemu. Nie ma sprzężenia z zależnością od podsystemu.

Metoda wtrysku:

To samo co wstrzykiwanie konstruktora, tyle że teraz konsument musi uzyskać konkretny przykład zależności od kontenera lub fabryki (lub nawet wstrzyknąć metodę / konstruktor) i wstrzyknąć go do metody. Znowu konsument nie jest powiązany z konkretnym wdrożeniem zależności.

TL; DR Najgorszym przypadkiem wstrzykiwania zależności w podsystemie jest przeniesienie sprzężenia na kod konsumenta. NIE MA OGÓLNEGO ZWIĘKSZENIA SPRZĘGŁA.

Najlepszym przypadkiem jest to, że wszystkie systemy są teraz luźno połączone, a wstrzykiwanie zależności jest kontrolowane przez pojemniki lub fabryki wstrzykiwania zależności.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.