Archiwum dla 'DEPENDENCY INJECTION' Kategoria

Wstrzykiwanie zależności czyli Dependency Injection. Część 5: wykorzystanie Google Guice

07.09.2009

W poprzednim odcinku widzieliśmy, jak można sobie ułatwić życie wstrzykując zależności do klas przy pomocy Springa [reszta cyklu: część 1., część 2., część 3.]. Dzisiaj czas na coś prostszego i przyjemniejszego: Google Guice!
Czytaj resztę wpisu »

Wstrzykiwanie zależności czyli Dependency Injection w 9 minut i 59 sekund. Część 4: wykorzystanie Spring-a

04.30.2009

Jak widzieliśmy [część 1., część 2., część 3.] wstrzykiwanie zależności jest całkiem sympatycznym pomysłem (o ile się go poprawnie używa), ale można zapytać się, na ile jest to kosztowne? Przez koszty rozumiem tutaj nakład pracy, jaki trzeba włożyć w używanie architektury wykorzystującej DI.

Wyobraźmy sobie, że nasza aplikacja często wykorzystuje klasę NewsService. Co to oznacza w praktyce? Za każdym razem musimy wstrzykiwać do niej zależność, których potrzebuje. Nasz przykład jest dość prosty, zależności nie ma zbyt wiele, ale nawet tutaj powtarzanie przy każdym użyciu kodu

public class Client {
  public static void main(String[] args) {
    Authenticator authenticator = new UsernamePassAuthenticator("beer","beer");
    Driver driver = new SqlDbDriver();

    //inject dependency #1
    Storage storage = new DBStorage(driver);
    //inject dependency #2
    NewsService newsService = new NewsService(storage);
    //inject dependency #3
    newsService.setAuthenticator(authenticator);

    newsService.addNews("ble ble ble");
  }
}

nie jest zbyt zachęcające. Czy nie lepiej jest użyć jednak jakiego wzorca factory czy service locator, żeby jednak NewsService sam sobie znalazł potrzebne klasy?
Czytaj resztę wpisu »

Wstrzykiwanie zależności czyli Dependency Injection w 9 minut i 59 sekund. Część 3: jak źle używać DI

04.10.2009

Kontynuujemy dalej naszą przeprawę z DI [część 1., część 2.]. W tym odcinku postaramy się w końcu coś popsuć – radosny marsz ścieżką usłaną różami jest przyjemny ale nie zawsze pouczający.

Zastanówmy się na ile użycie wstrzykiwania zależności czyni nasze oprogramowanie odpornym na błędy przy projektowaniu architektury aplikacji. W końcu nawet najwspanialszy wzorzec projektowy nie zabroni nam popełniania błędów.

Przyjrzyjmy się nieco zmodyfikowanej klasie NewsService

public class NewsService {

  Storage storage;
  Authenticator authenticator;

  public NewsService(Driver driver) {
    storage = new DBStorage(driver);
  }

  public Authenticator getAuthenticator() {
    return authenticator;
  }

  public void setAuthenticator(Authenticator authenticator) {
    this.authenticator = authenticator;
  }

  public void login(String uname, String pass){
    ((UsernamePassAuthenticator)authenticator).setUname(uname);
    ((UsernamePassAuthenticator)authenticator).setPass(pass);
  }

  public void addNews(String news){
    if(authenticator != null){
      authenticator.authenticate();
    }
    storage.save(news.getBytes());
    System.out.println("News saved...");
  }
}

Różni się ona od poprzedniej wersji w jednym drobnym, ale bardzo istotnym szczególe. Klasa NewsService w konstruktorze pobiera jako parametr sterownik (obiekt Driver), a nie, jak poprzednio Storage. W rezultacie NewsService sam sobie musi utworzyć obiekt Storage.

Kod NewsService jest wówczas związany na sztywno z konkretną implementacją kontenera na dane DBStorage, co jest oczywiście niepożądane. Co się zatem stało, co zrobiliśmy nie tak – w końcu używamy DI? A no popełniliśmy błąd polegający na tym, że wstrzykujemy do NewsService nie ten obiekt, co trzeba!

NewsService nie potrzebuje do niczego informacji o użytym sterowniku, NewsService potrzebuje tylko konkretnej implementacji Storage i to ona już ma się martwić o sterownik.

Ok. tutaj przypadek był prosty i ewidentny. W większych aplikacjach łatwo popełnić błąd polegający na wstrzyknięciu nie tego obiektu, który tak na prawdę jest wymagany. Także jeżeli widzimy, że gdzieś inicjalizacja klasy wymaga tworzenia obiektów, albo przekazujemy klasie jako parametr obiekty, które, logicznie rzecz biorąc, nie są jej potrzebne, to znaczy, że gdzieś położyliśmy architekturę aplikacji i błędnie użyliśmy DI.

Użycie DI wcale nie uwalnia nas od dobrego zaprojektowania aplikacji!

Wstrzykiwanie zależności czyli Dependency Injection w 9 minut i 59 sekund. Część 2: o tym, co tak właściwie robi DI

12.28.2008

W poprzednim wpisie znęcaliśmy się nad niezbyt gramotnie napisanym kawałkiem oprogramowania. Teraz przyszedł czas na napisanie wszystkiego tak, jak trzeba, w czym nam pomagać będzie właśnie wstrzykiwanie zależności.

Co nas najbardziej uwierało w poprzedniej wersji aplikacji? Tak na prawdę były to dwie rzeczy:

  1. Powiązania między klasami były zrealizowane przy użyciu referencji do konkretnych klas: jeżeli NewsService potrzebował mechanizmu do przechowywania informacji, to dawaliśmy mu referencję do klasy, która potrafiła przechowywać dane w SQL-owej bazie danych. Zmiana sposobu przechowywania danych na inny wymagała zmian w wielu miejscach w kodzie.
  2. Jeżeli klasa potrzebowała do pracy innej klasy, to sama musiała sobie utworzyć odpowiedni obiekt: NewsService potrzebując klasy do przechowywania danych sam sobie tworzył jej instancję.

Co w takim razie robi wstrzykiwanie zależności? Mówiąc ogólnie, w DI chodzi o to, żeby nie wiązać się z inną klasą poprzez użycie jej implementacji, tylko poprzez interfejs, pod który można podpiąć dowolną klasę go implementującą.

Dodatkowo, jeżeli nasza klasa potrzebuje konkretnej implementacji tego interfejsu, to nie powinna tej implementacji sama szukać czy jej tworzyć. Odpowiedni obiekt musi zostać do klasy “wstrzyknięty” w momencie inicjalizacji.

Zobaczmy, jak to wygląda w praktyce.
Czytaj resztę wpisu »

Wstrzykiwanie zależności, czyli Dependency Injection w 9 minut i 59 sekund. Część 1: podręczny przewodnik tworzenia złych aplikacji

12.23.2008

Gdzie się człowiek nie obejrzy tam się czai Dependency Injection (DI), czyli wstrzykiwanie zależności. Żeby jeszcze było tego mało, jak się zaczyna grzebać w internecie, to się co chwila można potknąć o jakiś framework, kontener czy coś takiego, co nam samo może zrobić Dependency Injection.

Co to w ogóle jest, po co takie coś komukolwiek, jak tego używać? Okazuje się, że sprawa jest prosta, wręcz banalna, a jednocześnie prowadzi do całkiem interesujących zastosowań. Za chwilę postaramy się zrozumieć jak DI działa, zrobimy to w sposób praktyczny, obdarty z krążących wokół DI ideologii i zupełnie zbędnego adżajlowego bełkotu.

Przekonamy się, że DI jest jednym z wielu możliwych sposobów budowania architektury aplikacji tak, by była łatwa w rozbudowie i testowaniu.

Będziemy chcieli zobaczyć coś więcej, niż zupełnie trywialny przykład (takich jest mnóstwo w internecie), po którym w zasadzie można wzruszyć ramionami, bo nie specjalnie widać tam jakiekolwiek zalety architektury wykorzystującej DI.

Naszym celem będzie zbudowanie bardzo prostej aplikacji służącej do przechowywania informacji, będzie składała się ona z trzech warstw (trójka jest nieprzypadkowa, sporo aplikacji Java EE jest rozbijane na tyle warstw) i tyluż komponentów.

Naszą aplikację napiszemy na kilka sposobów:

Zatem, do dzieła!
Czytaj resztę wpisu »