O różnicach pomiędzy wstrzykiwaniem via setter, a via pole z wykorzystaniem @PostConstruct

Szybko o tym dlaczego ta druga metoda jest zdecydowanie lepsza.

Generalnie po ustawieniu pola chcemy wykonać pewne operacje.

Wstrzykiwanie via setter

W guice adnotujemy @Inject metodę (dowolna nazwa, widoczność itp.) i to wszystko. Problem polega na tym, że obiekt jest w stanie nieokreślonym. Raz, że jego tworzenie jeszcze trwa, a dwa, że nie mamy kontroli nad kolejnością wywoływania metod.

Wstrzykiwanie via pole + @PostConstruct

W tym przypadku w momencie gdy metoda/y oznaczone @PostConstruct są wywoływane mamy pewność, że obiekt jest już zainicjowany i spójny. Plusem jest tu też możliwość ukrycia implementacji (brak setterów, metoda może być niewidoczna). Nadal nie mamy kontroli nad kolejnością wywołań w przypadku wielu metod @PostConstruct, ale zazwyczaj jedna wystarczy by w niej wykonać określone akcje w zadanej kolejności.

Gdzie to jest ważne

Takie coś może okazać się bardzo istotne w momencie gdy robicie DI na elementach GUI. Większość silników UI ma to do siebie, że dodając komponenty robi to w kolejności wywołania metod. Jedynym wyjątkiem są siatki, gdzie można kontrolować położenie komponentu w przestrzeni. Trochę inaczej ma się to w przypadku managerów wyglądu typu Vertical/Horizontal. Tam istotna jest kolejność wywołania metody. Zatem jeżeli nie chcecie stopki na górze strony…

2 myśli na temat “O różnicach pomiędzy wstrzykiwaniem via setter, a via pole z wykorzystaniem @PostConstruct

  1. Ostatnio gdzieś miałem okazję się wypowiedzieć: wstrzyknięcia przez konstruktor, pola final, chyba że ma być możliwość podmiany zależności w runtimie.
    W widoku akurat jako jedynym toleruje @inject (choć setter już nie specjalnie), jako że widok wedle założeń moich wszelakich, powinien być jeno tępym przekazicielem danych z warstwy biznesowej.

    Może nie jest to najwygodniejsze, ale mam wrażenie, że to ma najmniejszy ratio upierdliwość/czystość

  2. @Michał, będzie o tym jeszcze przy okazji ostatniej części Ekstremalnej Obiektowości, gdzie będę mówił o setterach i getterach.

    Generalnie pola final w połączeniu ze wstrzykiwaniem przez konstruktor są najlepszym rozwiązaniem. Jednak nie zawsze należy je stosować. Jest pewna grupa problemów, które charakteryzują się wzajemnymi zależnościami pomiędzy obiektami. Takimi dwuelementowymi cyklami. Roboczo nazywam to Granicą Koreańską (w praktyce jest to dwukierunkowy obserwator). W takim przypadku zarówno Spring jak i Guice tworzy jeszcze po drodze dynamiczne proxy. Problem polega jednak na tym, że takie rozwiązania mają tendencję do przyciągania kodu opartego o refleksję. Tym samym może okazać się, że obiekty zostały prawidłowo powiązane, ale nie za bardzo chcą współpracować.

Napisz odpowiedź

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax