Jak wytłumaczyć zastrzyk uzależnienia 5-latkowi? [Zamknięte]

208

Jaki jest dobry sposób na wyjaśnienie wstrzyknięcia zależności ?

Znalazłem kilka samouczków na temat Google, ale żaden z nich nie zakłada, że ​​czytelnik jest tylko początkującym językiem Java. Jak wytłumaczysz to nowicjuszowi?

użytkownik198313
źródło
72
Wygląda na to, że ten dzieciak
czeka
24
Zacznij od „Pewnego razu .....”
Martin
1
Czy mówimy o początkującym Javie, czy dosłownym pięciolatku?
Drew
2
# Zastrzyk zależności # nie zależy od wieku ucznia, dla każdego jest taki sam
Rakesh Juyal
2
Rakesh: wideo wprowadzające do JavaOne 2009 oparte jest na założeniu, że nawet 13 lat może być programistą Java, ponieważ Java jest „wszędzie” i „łatwa”.
Esko

Odpowiedzi:

789

Daję ci zastrzyk uzależnienia dla pięciolatków.

Kiedy idziesz i wyciągasz rzeczy z lodówki dla siebie, możesz powodować problemy. Możesz zostawić otwarte drzwi, możesz dostać coś, czego mama lub tata nie chcą, żebyś miał. Być może szukasz czegoś, czego nawet nie mamy lub które wygasło.

To, co powinieneś zrobić, to stwierdzenie potrzeby: „Potrzebuję czegoś do picia z lunchem”, a wtedy upewnimy się, że masz coś, kiedy usiądziesz i coś zjeść.

John Munsch
źródło
93

A co z tym?

Jeśli masz klasę, Employeea ten pracownik ją ma Address , możesz ją Employeezdefiniować w następujący sposób:

class Employee {
    private Address address;

    // constructor 
    public Employee( Address newAddress ) {
        this.address = newAddress;
    }

    public Address getAddress() {
    return this.address;
    }
    public void setAddress( Address newAddress ) {
        this.address = newAddress;
    }
}

Jak dotąd wszystko wygląda dobrze.

Ten kod pokazuje relację HAS-A między pracownikiem a jego adresem, w porządku.

Teraz ta relacja HAS-A stworzyła zależność między nimi. Problem dotyczy konstruktora.

Za każdym razem, gdy chcesz utworzyć Employeeinstancję, potrzebujesz Addressinstancji:

 Address someAddress = ....
 Employee oscar = new Employee( someAddress ); 

Praca w ten sposób staje się problematyczna, zwłaszcza gdy chcesz przeprowadzić testy jednostkowe.

Główny problem pojawia się, gdy musisz przetestować jeden konkretny obiekt, musisz utworzyć instancję innego obiektu, a najprawdopodobniej musisz utworzyć instancję jeszcze innego obiektu, aby to zrobić. Łańcuch może stać się niemożliwy do zarządzania.

Aby tego uniknąć, możesz zmienić konstruktor w następujący sposób:

  public Employee(){
  }

Korzystanie z konstruktora no args.

Następnie możesz ustawić adres, kiedy tylko chcesz:

 Address someAddress = ....
 Employee oscar = new Employee();
 oscar.setAddress( someAddress ); 

Może to być przeciąganie, jeśli masz kilka atrybutów lub obiekty są trudne do utworzenia.

Pomyśl o tym, powiedzmy, dodajesz Departmentatrybut:

  class Employee {
      private Address address;
      private Department department;

  ....

Jeśli masz 300 pracowników, a wszyscy muszą mieć ten sam dział, a ten sam dział musi być współużytkowany przez niektóre inne obiekty (takie jak lista firmowa działów lub role każdego działu itp.), Wtedy mają trudności z widocznością Departmentobiektu i udostępnieniem go przez całą sieć obiektów.

Na czym polega Dependence Injection , aby pomóc ci „wstrzyknąć” te zależności do twojego kodu. Większość ram pozwala to zrobić, określając w zewnętrznym pliku, jaki obiekt ma zostać wstrzyknięty.

Załóżmy plik właściwości dla wtryskiwacza fikcyjnej zależności:

  #mock employee
  employee.address = MockAddress.class
  employee.department = MockDepartment.class

  #production setup 
  employee.address = RealAddress.class
  employee.department = RealDepartment.class

Zdefiniujesz, co wstrzyknąć dla danego scenariusza.

To, co zrobi platforma Dependency Injector, to ustawienie odpowiednich obiektów dla ciebie, abyś nie musiał kodować setAddressani setDepartment. Odbyłoby się to poprzez refleksję, generowanie kodu lub inne techniki.

Zatem następnym razem, gdy będziesz musiał przetestować Employeeklasę, możesz wstrzyknąć próbkę Addressi Departmentsobiekty bez konieczności kodowania całego zestawu / get dla całego testu. Co więcej, możesz wstrzykiwać rzeczywiste Address i Departmentobiekty do kodu produkcyjnego i nadal mieć pewność, że Twój kod działa zgodnie z testami.

To właściwie tyle.

Nadal nie sądzę, aby to wyjaśnienie było odpowiednie dla 5-latka, jak prosiłeś.

Mam nadzieję, że nadal okaże się przydatny.

OscarRyz
źródło
3
Lub: Zastrzyki zależności są wtedy, gdy masz coś, co ustawia dla Ciebie zależności. To coś jest zwykle ramą. :)
OscarRyz
2
naprawdę bardzo mądry.
OscarRyz
24

Podczas pisania zajęć naturalne jest, że korzysta z innych obiektów. Możesz mieć na przykład połączenie z bazą danych lub inną usługę, z której korzystasz. Te inne obiekty (lub usługi) są zależnościami. Najprostszym sposobem na napisanie kodu jest po prostu utworzenie i użycie tych innych obiektów. Ale to oznacza, że ​​twój obiekt ma nieelastyczny związek z tymi zależnościami: bez względu na to, dlaczego wywołujesz swój obiekt, używa tych samych zależności.

Bardziej zaawansowaną techniką jest możliwość stworzenia obiektu i zapewnienia mu zależności do użycia. Możesz więc utworzyć połączenie z bazą danych do użycia, a następnie przekazać je swojemu obiektowi. W ten sposób możesz stworzyć swój obiekt z różnymi zależnościami w różnym czasie, dzięki czemu Twój obiekt będzie bardziej elastyczny. Jest to wstrzykiwanie zależności, polegające na „wstrzyknięciu” zależności do obiektu.

BTW: W nowoczesnym stylu prezentacji wykorzystującym zdjęcia Flickr do zilustrowania koncepcji, można to zilustrować uzależnionym strzelającym z narkotykami. Och, czekaj, to zależność od iniekcji ... OK, przepraszam, zły żart.

Ned Batchelder
źródło
10

Nie znam żadnych uproszczonych samouczków, ale mogę dać ci prawie 25 250 słów lub mniej wersji:

W przypadku wstrzykiwania zależności obiekt nie konfiguruje własnych składników w oparciu o rzeczy, które już zna, raczej obiekt jest konfigurowany za pomocą logiki wyższego poziomu, a następnie wywołuje komponenty, o których nie ma wbudowanej wiedzy wstępnej. Chodzi o to, aby obiekt był bardziej składnikiem, a mniej aplikacją, przenosząc zadania konfiguracyjne na wyższy poziom. Dzięki temu obiekt będzie bardziej przydatny w przyszłości lub przy innej konfiguracji.

Jest lepszy do testowania, lepiej, gdy przychodzi czas na poprawienie aplikacji. Typowa implementacja umieszcza konfigurację w formacie XML i wykorzystuje strukturę do dynamicznego ładowania klas.

DigitalRoss
źródło
7

Gdy otrzymasz nowe Nintendo, możesz po prostu używać przycisków i ekranu dotykowego, aby grać w gry.

Ale w fabryce Nintendo muszą wiedzieć, jak je połączyć.

Kiedy inteligentni ludzie w fabryce wypuszczą konsolę Nintendo DS, wewnątrz będzie inaczej, ale nadal będziesz wiedział, jak z niej korzystać.

W W.
źródło
5
To brzmi bardziej jak opis interfejsów lub polimorfizmu, ale przyznaję, że naprawdę jesteś zrozumiały dla 5-latka.
Natix