Według artykułu napisanego przez Martina Fowlera , odwrócenie kontroli jest zasadą, w której przepływ sterowania programem jest odwrócony: zamiast programisty kontrolującego przepływ programu, źródła zewnętrzne (szkielet, usługi, inne komponenty) przejmują kontrolę to. To tak, jakbyśmy podłączali coś do czegoś innego. Wspomniał przykład o EJB 2.0:
Na przykład interfejs Session Bean definiuje ejbRemove, ejbPassivate (przechowywany w pamięci dodatkowej) i ejbActivate (przywracany ze stanu pasywnego). Nie można kontrolować, kiedy te metody są wywoływane, tylko to, co robią. Kontener dzwoni do nas, nie nazywamy tego.
Prowadzi to do różnicy między frameworkiem a biblioteką:
Odwrócenie kontroli jest kluczową częścią tego, co odróżnia framework od biblioteki. Biblioteka jest zasadniczo zbiorem funkcji, które można wywoływać, w dzisiejszych czasach zwykle są one zorganizowane w klasy. Każde połączenie wykonuje pewną pracę i zwraca kontrolę klientowi.
Myślę, że punkt widzenia, że DI to MKOl, oznacza, że zależność obiektu jest odwrócona: zamiast kontrolować własne zależności, cykl życia ... coś innego robi dla ciebie. Ale, jak powiedziałeś mi o DI ręcznie, DI niekoniecznie musi być MKOl. Nadal możemy mieć DI i brak MKOl.
Jednak w tym artykule (z pococapsule, innej struktury IOC dla C / C ++) sugeruje, że z powodu IOC i DI, kontenery IOC i struktury DI są znacznie lepsze od J2EE, ponieważ J2EE miesza kod struktury z komponentami , nie czyniąc go więc Plain Old Java / C ++ Object (POJO / POCO).
Inwersja kontenerów kontrolnych innych niż wzorzec wstrzykiwania zależności (link do archiwum)
Dodatkowa lektura, aby zrozumieć, na czym polega problem ze starą platformą programistyczną opartą na komponentach, co prowadzi do drugiego artykułu powyżej: Dlaczego i co z inwersją kontroli (link do archiwum)
Moje pytanie : Czym dokładnie jest MKOl i DI? Jestem zdezorientowany. Oparty na pococapsule, IOC jest czymś ważniejszym niż odwrócenie kontroli między obiektami, programistami i frameworkami.
Odpowiedzi:
IoC to ogólny termin, który oznacza, że aplikacja nie wywołuje metod w ramach, a platforma wywołuje implementacje dostarczone przez aplikację.
DI jest formą IoC, w której implementacje są przekazywane do obiektu przez wyszukiwanie konstruktorów / ustawiaczy / usług, od których obiekt będzie „zależał”, aby zachowywać się poprawnie.
IoC bez korzystania z DI , na przykład, byłby wzorzec szablonu, ponieważ implementację można zmienić tylko poprzez podklasę.
Ramy DI są zaprojektowane do korzystania z DI i mogą definiować interfejsy (lub Adnotacje w Javie), aby ułatwić przekazywanie w implementacjach.
Kontenery IoC to frameworki DI, które mogą działać poza językiem programowania. W niektórych można skonfigurować, które implementacje mają być używane w plikach metadanych (np. XML), które są mniej inwazyjne. Z niektórymi możesz zrobić IoC, co normalnie byłoby niemożliwe, jak wstrzyknięcie implementacji na punktach cięcia .
Zobacz także ten artykuł Martina Fowlera .
źródło
Krótko mówiąc, IoC jest znacznie szerszym pojęciem, które obejmuje między innymi DI
Termin Inversion of Control (IoC) pierwotnie oznaczał dowolny styl programowania, w którym ogólna struktura lub środowisko wykonawcze kontrolowało przebieg programu
Zanim DI miał swoją nazwę, ludzie zaczęli odnosić się do frameworków zarządzających zależnościami jako Inversion of Control Containers, a wkrótce znaczenie IoC stopniowo zmieniło się w to szczególne znaczenie: Inversion of Control over Dependencies.
Inwersja kontroli (IoC) oznacza, że obiekty nie tworzą innych obiektów, na których polegają w swojej pracy. Zamiast tego pobierają potrzebne im obiekty ze źródła zewnętrznego (na przykład plik konfiguracyjny xml).
Wstrzykiwanie zależności (DI) oznacza, że odbywa się to bez interwencji obiektu, zwykle przez komponent szkieletowy, który przekazuje parametry konstruktora i ustawia właściwości.
źródło
źródło
IoC ( I nWersja O F C kontroli twoj ego): - Jest to ogólny termin i realizowane na kilka sposobów (imprezy delegaci etc).
DI ( wstrzyknięcie D ependencji I ): - DI jest podtypem IoC i jest implementowany przez wstrzyknięcie konstruktora, wstrzyknięcie setera lub wstrzyknięcie interfejsu .
Ale Spring obsługuje tylko następujące dwa typy:
NullPointerException: bean does not exist
. Wstrzykiwanie przez konstruktora jest najlepszą praktyką do wstrzykiwania zależności.źródło
DI jest podzbiorem IoC
Oto kilka innych technik osiągnięcia IoC .
źródło
Ponieważ wszystkie odpowiedzi podkreślają teorię, chciałbym zademonstrować na przykładzie pierwszego podejścia:
Załóżmy, że tworzymy aplikację, która zawiera funkcję wysyłania wiadomości SMS z potwierdzeniem po wysłaniu zamówienia. Będziemy mieć dwie klasy, jedną odpowiedzialną za wysyłanie SMS-ów (SMSService), a drugą odpowiedzialną za przechwytywanie danych wejściowych użytkownika (UIHandler), nasz kod będzie wyglądał jak poniżej:
Powyższa implementacja nie jest zła, ale jest kilka problemów:
-) Załóżmy, że w środowisku programistycznym chcesz zapisywać SMS-y wysyłane do pliku tekstowego zamiast bramy SMS, aby to osiągnąć; w końcu zmienimy konkretną implementację (SMSService) na inną implementację, tracimy elastyczność i zmuszeni jesteśmy przepisać kod w tym przypadku.
-) Skończy się mieszanie obowiązków klas, nasz (UIHandler) nigdy nie powinien wiedzieć o konkretnej implementacji (SMSService), należy to zrobić poza klasami za pomocą „Interfejsów”. Gdy zostanie to zaimplementowane, da nam możliwość zmiany zachowania systemu poprzez zamianę (SMSService) używanej z inną próbną usługą, która implementuje ten sam interfejs, usługa ta zapisuje SMS-y do pliku tekstowego zamiast wysyłania do mobileNumber.
Aby rozwiązać powyższe problemy, używamy interfejsów, które zostaną zaimplementowane przez nasz (SMSService) i nowy (MockSMSService), w zasadzie nowy interfejs (ISMSService) ujawni takie same zachowania obu usług, jak poniższy kod:
Następnie zmienimy naszą implementację (SMSService) na implementację interfejsu (ISMSService):
Teraz będziemy mogli stworzyć nową usługę makiety (MockSMSService) z zupełnie inną implementacją przy użyciu tego samego interfejsu:
W tym momencie możemy zmienić kod w (UIHandler), aby łatwo użyć konkretnej implementacji usługi (MockSMSService), jak poniżej:
Osiągnęliśmy dużą elastyczność i wprowadziliśmy separację problemów w naszym kodzie, ale nadal musimy dokonać zmiany w podstawie kodu, aby przełączać się między dwiema usługami SMS. Musimy więc wdrożyć Dependency Injection .
Aby to osiągnąć, musimy zaimplementować zmianę w naszym konstruktorze klasy (UIHandler), aby przekazać przez nią zależność. W ten sposób kod korzystający z (UIHandler) może określić, która konkretna implementacja (ISMSService) użyć:
Teraz formularz interfejsu użytkownika, który będzie rozmawiał z klasą (UIHandler), jest odpowiedzialny za przekazanie implementacji interfejsu (ISMSService) do wykorzystania. Oznacza to, że odwróciliśmy kontrolę, (UIHandler) nie jest już odpowiedzialny za decyzję, której implementacji użyć, robi to kod wywołujący. Wdrożyliśmy zasadę Inwersji Kontroli, której DI jest jednym z jej rodzajów.
Kod formularza interfejsu użytkownika będzie następujący:
źródło
IOC (Inversion Of Control) : Przekazanie kontroli kontenerowi w celu uzyskania instancji obiektu nazywa się Inversion of Control, co oznacza, że zamiast tworzyć obiekt za pomocą nowego operatora, pozwól kontenerowi zrobić to za Ciebie.
DI (Dependency Injection) : Sposób wstrzykiwania właściwości do obiektu nazywa się Dependency Injection .
Mamy trzy rodzaje wstrzykiwania zależności :
Sprężyna obsługuje tylko wtrysk konstruktora i wtrysk Settera / Gettera .
źródło
Ale wiosenna dokumentacja mówi, że są takie same.
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-introduction
W pierwszym wierszu „ IoC jest również znany jako wstrzykiwanie zależności (DI) ”.
źródło
IoC - Odwrócenie kontroli jest terminem ogólnym, niezależnym od języka, w rzeczywistości nie tworzy obiektów, lecz opisuje, w jaki sposób powstaje obiekt mody.
DI - Dependency Injection to konkretny termin, w którym zapewniamy zależności obiektu w czasie wykonywania przy użyciu różnych technik wstrzykiwania, a mianowicie. Zastrzyk setera, wtrysk konstruktora lub wstrzyknięcie interfejsu.
źródło
Odwrócenie kontroli to paradygmat projektowania, którego celem jest zapewnienie większej kontroli nad docelowymi komponentami aplikacji, które wykonują pracę.
Wstrzykiwanie zależności jest wzorcem używanym do tworzenia instancji obiektów, na których polegają inne obiekty bez wiedzy w czasie kompilacji, która klasa zostanie użyta do zapewnienia tej funkcjonalności.
Istnieje kilka podstawowych technik wdrażania odwrócenia kontroli. To są:
1). Zastrzyk konstruktora
2). Zastrzyk setera
3). Wstrzyknięcie interfejsu
źródło
DI i IOC to dwa wzorce projektowe, które koncentrują się głównie na zapewnieniu luźnego sprzężenia między komponentami , lub po prostu sposobem, w którym rozłączamy konwencjonalne zależności zależności między obiektami, aby obiekty nie były do siebie szczelne.
W poniższych przykładach próbuję wyjaśnić oba te pojęcia.
Wcześniej piszemy taki kod
W przypadku wstrzykiwania zależności wtryskiwacz zależności zajmie się tworzeniem obiektów
Powyższy proces przekazania kontroli innemu (np. Kontenerowi) instancji i iniekcji można nazwać inwersją kontroli, a proces, w którym pojemnik IOC wstrzykuje dla nas zależność, można nazwać iniekcją zależności.
IOC jest zasadą, w której przepływ sterujący programu jest odwrócony: zamiast programisty sterującego przepływem programu , program steruje przepływem poprzez zmniejszenie narzutu na programistę . A proces wykorzystywany przez program do wstrzykiwania zależności jest określany jako DI
Obie koncepcje współpracują ze sobą, zapewniając nam sposób na napisanie znacznie bardziej elastycznego, wielokrotnego użytku i enkapsulowanego kodu, co czyni je ważnymi koncepcjami w projektowaniu rozwiązań obiektowych.
Polecam również przeczytać.
Co to jest wstrzyknięcie zależności?
Możesz również sprawdzić jedną z moich podobnych odpowiedzi tutaj
Różnica między inwersją kontroli i iniekcji zależności
źródło
Inwersja kontroli to ogólna zasada projektowania architektury oprogramowania, która pomaga w tworzeniu łatwych w utrzymaniu modułowych struktur oprogramowania wielokrotnego użytku.
Jest to zasada projektowa, w której przepływ kontroli jest „odbierany” z biblioteki zapisanej w formie ogólnej lub kodu wielokrotnego użytku.
Aby to lepiej zrozumieć, zobaczmy, jak kodowaliśmy w naszych wcześniejszych czasach kodowania. W językach proceduralnych / tradycyjnych logika biznesowa ogólnie kontroluje przepływ aplikacji i „wywołuje” ogólny kod lub funkcje wielokrotnego użytku. Na przykład w prostej aplikacji konsoli mój przepływ kontroli jest kontrolowany przez instrukcje mojego programu, które mogą obejmować wywołania niektórych ogólnych funkcji wielokrotnego użytku.
Natomiast w przypadku IoC frameworki to kod wielokrotnego użytku, który „wywołuje” logikę biznesową.
Na przykład w systemie opartym na systemie Windows dostępna będzie już platforma do tworzenia elementów interfejsu użytkownika, takich jak przyciski, menu, okna i okna dialogowe. Kiedy piszę logikę biznesową mojej aplikacji, to zdarzenia frameworka będą wywoływały mój kod logiki biznesowej (po uruchomieniu zdarzenia), a NIE odwrotnie.
Chociaż kod frameworka nie zna mojej logiki biznesowej, nadal będzie wiedział, jak wywołać mój kod. Osiąga się to za pomocą zdarzeń / delegatów, wywołań zwrotnych itp. Tutaj kontrola przepływu jest „odwrócona”.
Zatem zamiast zależeć od przepływu kontroli na statycznie związanych obiektach, przepływ zależy od ogólnego wykresu obiektów i relacji między różnymi obiektami.
Dependency Injection to wzorzec projektowy, który implementuje zasadę IoC do rozwiązywania zależności obiektów.
Mówiąc prościej, kiedy próbujesz pisać kod, będziesz tworzyć i używać różnych klas. Jedna klasa (klasa A) może używać innych klas (klasa B i / lub D). Tak więc klasy B i D są zależnościami klasy A.
Prostą analogią będzie samochód klasy. Samochód może zależeć od innych klas, takich jak silnik, opony i inne.
Wstrzykiwanie zależności sugeruje, że zamiast klas zależnych (tutaj samochód klasy) tworzących zależności (silnik klasy i opona klasy), klasy należy wstrzyknąć konkretny przykład zależności.
Pozwala zrozumieć bardziej praktyczny przykład. Zastanów się, czy piszesz własnego TextEditora. Między innymi możesz mieć moduł sprawdzania pisowni, który zapewnia użytkownikowi możliwość sprawdzania literówek w jego tekście. Prostą implementacją takiego kodu może być:
Na pierwszy rzut oka wszystko wygląda różowo. Użytkownik napisze tekst. Deweloper przechwyci tekst i wywoła funkcję CheckSpellings i znajdzie listę literówek, które pokaże użytkownikowi.
Wydaje się, że wszystko działa świetnie, aż pewnego pięknego dnia, gdy jeden użytkownik zacznie pisać po francusku w edytorze.
Aby zapewnić obsługę większej liczby języków, potrzebujemy więcej sprawdzania pisowni. Prawdopodobnie francuski, niemiecki, hiszpański itp.
Tutaj stworzyliśmy ściśle powiązany kod z „angielskim” SpellCheckerem ściśle powiązanym z naszą klasą TextEditor, co oznacza, że nasza klasa TextEditor jest zależna od EnglishSpellChecker lub innymi słowy EnglishSpellCheker jest zależnością dla TextEditor. Musimy usunąć tę zależność. Co więcej, nasz edytor tekstu potrzebuje sposobu, aby zachować konkretne odniesienie do dowolnego modułu sprawdzania pisowni w oparciu o uznanie programisty w czasie wykonywania.
Tak więc, jak widzieliśmy we wprowadzeniu DI, sugeruje, że klasie należy wstrzyknąć swoje zależności. Zatem obowiązkiem kodu wywołującego jest wstrzyknięcie wszystkich zależności do wywoływanej klasy / kodu. Możemy więc zrestrukturyzować nasz kod jako
W naszym przykładzie klasa TextEditor powinna otrzymać konkretną instancję typu ISpellChecker.
Teraz zależność można wprowadzić do Konstruktora, własności publicznej lub metody.
Spróbujmy zmienić naszą klasę za pomocą Constructor DI. Zmieniona klasa TextEditor będzie wyglądać mniej więcej tak:
Aby kod wywołujący podczas tworzenia edytora tekstu mógł wstrzyknąć odpowiedni typ sprawdzania pisowni do instancji TextEditor.
Możesz przeczytać cały artykuł tutaj
źródło
IOC (Inversion Of Control): Przekazanie kontroli kontenerowi w celu uzyskania instancji obiektu nazywa się Inversion of Control. Oznacza to, że zamiast tworzyć obiekt za pomocą nowego operatora , niech kontener zrobi to za Ciebie.
DI (wstrzykiwanie zależności): Przekazywanie wymaganych parametrów (właściwości) z XML do obiektu (w KLASIE POJO) nazywa się wstrzykiwaniem zależności.
źródło
IOC wskazuje, że klasy zewnętrzne zarządzające klasami aplikacji, a klasy zewnętrzne oznaczają, że kontener zarządza zależnością między klasami aplikacji. podstawową koncepcją MKOl jest to, że programista nie musi tworzyć twoich obiektów, ale opisuje, w jaki sposób powinny być one tworzone.
Główne zadania wykonywane przez kontener IoC to: tworzenie instancji klasy aplikacji. skonfigurować obiekt. aby zestawić zależności między obiektami.
DI to proces zapewniania zależności obiektu w czasie wykonywania przy użyciu wstrzykiwania setera lub wstrzykiwania konstruktora.
źródło
IOC (Inversion of Control) to zasadniczo koncepcja wzorca projektowania polegająca na usuwaniu zależności i rozdzielaniu ich w celu uczynienia przepływu nieliniowym, i pozwala kontenerowi / lub innemu podmiotowi zarządzać udostępnianiem zależności. W rzeczywistości jest to zgodne z zasadą Hollywood: „Nie dzwoń do nas, my zadzwonimy”. Podsumowując różnice.
Odwrócenie kontroli: - Jest to ogólny termin na rozdzielenie zależności i delegowanie ich udostępniania, i można to zrealizować na kilka sposobów (zdarzenia, delegaci itp.).
Iniekcja zależności: - DI jest podtypem IOC i jest realizowana przez iniekcję konstruktora, iniekcję setera lub metodę iniekcji.
Poniższy artykuł opisuje to bardzo starannie.
https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO
źródło
Myślę, że pomysł można jasno przedstawić bez wchodzenia w chwasty zorientowane obiektowo, które wydają się mętne.
Jeśli przechylisz głowę i zmrużysz oczy, zobaczysz, że DI jest szczególną implementacją IoC z konkretnymi obawami. Zamiast wstrzykiwać modele i zachowania do środowiska aplikacji lub operacji wyższego rzędu, wstrzykujesz zmienne do funkcji lub obiektu.
źródło
Zacznijmy od D z SOLID i spójrzmy na DI i IoC z książki Scotta Milletta „Professional ASP.NET Design Patterns”:
Millett, C (2010). Profesjonalne wzorce projektowe ASP.NET. Wiley Publishing. 7-8.
źródło
// ICO, DI, 10 lat temu, tak było:
Teraz z wiosną 3,4 lub najnowszą jest jak poniżej
Ogólnie rzecz biorąc, kontrola jest odwrócona od starej koncepcji sprzężonego kodu do struktur takich jak Spring, która udostępnia obiekt. To jest IOC, o ile wiem, i wstrzykiwanie zależności, jak wiesz, gdy wstrzykujemy zależny obiekt do innego obiektu za pomocą Konstruktora lub ustawiaczy. Zastrzyk zasadniczo oznacza przekazanie go jako argumentu. Wiosną mamy konfigurację opartą na XML i adnotacjach, w której definiujemy obiekt komponentu bean i przekazujemy obiekt zależny za pomocą stylu iniekcji konstruktora lub setera.
źródło
Znalazłem najlepszy przykład na Dzone.com, który naprawdę pomaga zrozumieć prawdziwe różnice między IOC i DI
Przeczytaj cały artykuł MKOl i Przeczytaj cały artykuł DI
źródło
1) DI to Child-> obj zależy od parent-obj. Czasownik zależy jest ważny. 2) IOC to Child-> obj występujące pod platformą. gdzie platformą może być szkoła, college, klasa taneczna. Tutaj perform jest działaniem o różnych implikacjach pod dowolnym dostawcą platformy.
praktyczny przykład: `
`
-AB
źródło
Jeśli chodzi o to pytanie, powiedziałbym, że wiki zawiera już szczegółowe i łatwe do zrozumienia wyjaśnienia. Przytoczę tutaj najważniejsze.
Wdrożenie IoC
Co do wstrzykiwania zależności
źródło
Koncepcja IoC była początkowo słyszana w erze programowania proceduralnego. Dlatego z historycznego kontekstu IoC mówił o inwersji własności kontrolno przepływu tj. O tym, kto jest odpowiedzialny za wywoływanie funkcji w pożądanej kolejności - niezależnie od tego, czy są to same funkcje, czy też należy je odwrócić na jakąś jednostkę zewnętrzną.
Jednak po pojawieniu się OOP ludzie zaczęli rozmawiać o IoC w kontekście OOP, w którym aplikacje zajmują się także tworzeniem obiektów i ich relacjami, oprócz przepływu sterowania. Takie aplikacje chciały odwrócić własność tworzenia obiektów (a nie kontroli przepływu) i wymagały kontenera, który jest odpowiedzialny za tworzenie obiektów, cykl życia obiektu i wstrzykiwanie zależności obiektów aplikacji, eliminując w ten sposób obiekty aplikacji z tworzenia innego konkretnego obiektu.
W tym sensie DI nie jest tym samym co Io C , ponieważ nie dotyczy przepływu sterowania, ale jest rodzajem Io * , czyli odwróceniem własności tworzenia obiektów.
Co jest złego w moim sposobie wyjaśniania DI i IoC?
źródło