Zasada inwersji zależności: jak zdefiniować „politykę wysokiego poziomu” i „szczegóły niskiego poziomu” dla innych osób?


13

Próbuję wyjaśnić zasadę inwersji zależności moim (głównie młodszym) kolegom. Jak możemy zdefiniować, która jest „polityką wysokiego poziomu”, a która „szczegółem niskiego poziomu” w oprogramowaniu? Na przykład, jeśli nasze oprogramowanie automatyzuje przepływ pracy kilku aplikacji biznesowych, dlaczego mówimy, że automatyzacja przepływu pracy jest polityką wysokiego poziomu, a aplikacje biznesowe są szczegółami?

Odpowiedzi:


11

Uwaga: zostało to całkowicie przepisane z mojego wcześniejszego przykładu

Pomyśl o gniazdach zasilania. W każdym kraju polityka wysokiego poziomu mówi, że gniazdka zasilania są zawsze takie same. Nie ma znaczenia, skąd czerpiesz energię elektryczną (węgiel, gaz, energia jądrowa), gniazda na ścianie powinny zawsze wytwarzać taką samą moc, przez ten sam zestaw złączy.

Teraz możesz podłączyć dowolne urządzenie do tego gniazda, ponieważ wszystkie mają wspólny interfejs, „wtyczkę”. Polityka wysokiego poziomu nigdy nie musi dyktować żadnej części szczegółów implementacji. Po prostu podłącz coś i gotowe.

Teraz, jeśli masz urządzenie, które nie chce zasilania prądem przemiennym - być może działa ono na obwodzie prądu stałego 7 V - nadal możesz korzystać z tej polityki wysokiego poziomu, potrzebujesz tylko pewnego rodzaju adaptera między zasilaczem a urządzeniem. A ponieważ wszyscy mają takie same zasady wysokiego poziomu, producent może je wbudować w implementację bez żadnych zmian w polityce wysokiego poziomu. Osoba łącząca implementację z zasadami (ty, podłączając laptopa) tak naprawdę nie musi tego rozumieć.

Ponadto, jeśli producent chce sprzedawać to samo urządzenie w innym kraju, wystarczy opracować inny adapter. Tak więc ta sama implementacja może działać z wieloma politykami, podczas gdy ta sama polityka może uruchamiać wiele implementacji.

To doskonały przykład odwrócenia zależności.

Ale oto interesujący fragment: wróć do tego, co powiedziałem po raz pierwszy. „Nie ma znaczenia, skąd bierzesz prąd.” Jest to również szczegół implementacji. Nadrzędną zasadą jest nadal to, że wszystkie gniazda zasilania mają ten sam kształt i emitują ten sam rodzaj zasilania. Szczegóły implementacji niskiego poziomu dotyczą zarówno źródła energii elektrycznej, jak i jej przebiegu.

W kategoriach programowych oznacza to, że polityka wysokiego poziomu jest interfejsem (tam, gdzie obsługuje ją język. Inną formą DI jest pisanie na klawiaturze). Interfejs API zapewnia i aplikacja zużywa, a szczegóły implementacji niskiego poziomu są zarówno aplikacja go zużywa i sam interfejs API, z których żaden nie musi się rozumieć.

Do dopasowania tej samej implementacji do różnych zasad można użyć adapterów.


+1 Crikey. Nie wiedziałem, że tyle mogę się nauczyć z prostego gniazdka :)
dreza

7

Klasyczne podejście do ponownego wykorzystania oprogramowania polega na budowaniu komponentów, które zależą od niczego innego (co czyni je niskopoziomowymi), a następnie budowaniu komponentów wyższego poziomu, które zależą od komponentów niższego poziomu. „wysoki poziom” i „niski poziom” są określone przez kierunek zależności, który nie jest nieodłączny od funkcji komponentu, ale często jest jedynie decyzją architektoniczną.

Tak więc, gdy budowane są pojedyncze aplikacje biznesowe bez zależności od automatyzacji przepływu pracy, ale kontroler przepływu pracy ma bezpośrednie zależności od aplikacji biznesowej, wówczas powinno być jasne, że automatyzacja przepływu pracy jest „polityką wysokiego poziomu”, a aplikacja biznesowa jest składnik „niskiego poziomu”. Należy pamiętać, że ta struktura nie jest obowiązkowa - jeśli komponent automatyzacji przepływu pracy jest ogólną strukturą, która nie jest sprzężona z konkretnymi aplikacjami biznesowymi, ale może być skonfigurowana do obsługi różnych aplikacji, oznacza to, że już zacząłeś stosować DIP. W tej sytuacji separacja „wysokiego poziomu” / „niskiego poziomu” może już nie mieć sensu między tymi dwiema rzeczami.

Tak więc nazwa „inwersja zależności” jest nieco myląca - ponieważ zależności nie są „odwrócone”, ale całkowicie usunięte (lub ściślej: zmieniono je z zależności kompilacji czasu kompilacji na zależności w czasie wykonywania).


1
Nie do końca. Inwersja ma miejsce, ponieważ niższe poziomy zależą od interfejsu. Stosując zasadę segregacji interfejsu (I w SOLID), interfejs ten „należy” do klienta. Zatem niższy poziom metaforycznie bierze zależność od klienta.
Michael Brown

2
@MikeBrown: to jeden z możliwych punktów widzenia. Wolę punkt widzenia, w którym interfejs nie należy ani do A, ani do B, ale do infrastruktury lub środowiska A i B.
Doc Brown

1

Używam prostego obrazu, aby wyjaśnić DIP. Klasyczne spojrzenie na tworzenie oprogramowania jest procesem konstrukcyjnym, w którym każda warstwa znajduje się na wierzchu niższych warstw, które ją obsługują. Korzystanie z zasady inwersji zależności jest bardziej jak budowanie telefonu komórkowego.Hanging Mobile

Zamiast wyższych warstw leżących na niższych warstwach, wyższe warstwy w interfejsie mobilnym z niższymi warstwami za pośrednictwem ciągu, który je łączy. W pewnym sensie niższe warstwy zależą od tego interfejsu do obsługi (bez łańcucha, który spadłyby). To DIP w pigułce.


+1 za miłe porównanie. Na tym obrazie możesz zobaczyć mój punkt widzenia - wszystkie warstwy zależą od interfejsów, ale nie niższe warstwy na wyższych lub odwrotnie.
Doc Brown

Rozumiem, co mówisz, interfejs nie należy ani do wyższego, ani do niższego poziomu.
Michael Brown

1
Nie zapytał, jak wyjaśnić DIP, zapytał, w jaki sposób wyjaśnić, które części aplikacji są zasadami wysokiego poziomu, a które implementacjami niskiego poziomu. Twoja analogia nie musi się daleko rozciągać, aby to zrobić. Musisz tylko móc zmieniać dekoracje bez zmiany łańcucha (bo jeśli nie możesz, wówczas zasady mobilne wysokiego poziomu zawierają zbyt wiele szczegółów na temat implementacji dekoracji).
pdr

1
(i w rzeczywistości możesz zbudować zupełnie nowy telefon komórkowy z różnych materiałów i powiesić na nim te same dekoracje - co jest celem Doc Browna)
pdr
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.