5

Obecnie eksperymentuję z inwersją GUice kontenera sterowania. Poprzednio miałem single dla jakiejkolwiek usługi (bazy danych, aktywnego katalogu), z której korzystałem. Teraz refaktoryzowałem kod: wszystkie zależności są podawane jako parametry dla konstruktorów. Jak na razie dobrze. Teraz najtrudniejszą częścią jest graficzny interfejs użytkownika. Spotykam się z tym problemem: mam tabelę (JTable) produktów owiniętych w ProductFrame. Podaję zależności jako parametry (EditProductDialog).Czy iniekcja zależności dotyczy tylko obiektów typu usługi i pojedynczych obiektów? (a NIE dla GUI?)

@Inject 
public ProductFrame(EditProductDialog editProductDialog) { 
    // ... 
} 

// ... 

@Inject 
public EditProductDialog(DBProductController productController, Product product) { 
    // ... 
} 

Problemem jest to, że Guice nie może wiedzieć, jaki produkt wybrałem w tabeli, więc nie może wiedzieć, co wstrzykiwać w EditProductDialog.

Wstrzykiwanie zależności jest dość wirusowe (jeśli zmodyfikuję jedną klasę, aby użyć wstrzyknięcia zależności, muszę również zmodyfikować wszystkie inne klasy, z którymi wchodzi w interakcje), więc moje pytanie brzmi: czy powinienem bezpośrednio utworzyć instancję EditProductDialog? Ale wtedy musiałbym ręcznie przekazać DBProductController do EditProductDialog i będę również musiał przekazać go do ProductFrame, a wszystko to sprowadza się do tego, aby w ogóle nie używać iniekcji zależności.

Czy mój projekt jest wadliwy i z tego powodu nie mogę tak naprawdę zaadaptować projektu do iniekcji dependecy?

Podaj mi kilka przykładów wykorzystania wtrysku zależności w graficznym interfejsie użytkownika. Wszystkie przykłady znalezione w Internecie są naprawdę prostymi przykładami korzystania z niektórych usług (głównie baz danych) z zastrzykiem zależności.

Odpowiedz

1

Z tego, co widzę w przykładowym kodzie, nie jestem pewien, czy przekazanie Product do EditProductDialog jest najlepszym projektem, oznacza to, że nie można ponownie użyć tego samego okna dialogowego dla 2 różnych produktów.

Ogólnie wolałbym dodać setProduct(Product) do EditProductDialog w celu: ponowne

  • umożliwienia tego samego dialogowym
  • umożliwić zastrzyk konstruktora samego okna

Poza tym, może również, jeśli chcesz zachować bieżące argumenty konstruktora, spójrz na Guice Assisted Injection, która umożliwiłaby wstrzyknięcie wszystkich zależności do konstruktora, jednocześnie zapewniając jawne udostępnienie produktu .

Wreszcie, warto przyjrzeć się Guts-GUI, strukturze open source do tworzenia graficznych interfejsów Swing z Guice (wciąż działa, ale jest gotowy do użycia od dzisiaj). Ma przykładową aplikację, która zawiera przykłady okien wielokrotnego użytku.

+0

Myślałem o tym samym rozwiązaniu, ale nie byłem pewien, czy jest to najlepsze podejście, ponieważ przy wstrzyknięciu zależności "musisz zadeklarować swoje zależności" (w konstruktorze w przypadku guice). Ale teraz wydaje się to najlepszym rozwiązaniem. Dzięki za linki. Są zdecydowanie pomocni !!! –

+0

Innym podejściem, o którym myślałem było użycie guice tylko dla usług (baza danych itp.) I dla klas gui, aby przekazać wtryskiwacz jako parametr. Nie jestem też pewien tego podejścia. –

+1

Nie rób tego! Bezpośrednie użycie Guice Injector w kodzie aplikacji musi być uważane za zapach projektu, jest to sprzeczne z "Inversion of Control" i wygląda jak "wzór fabryczny". Tylko ramy lub biblioteki mogą mieć taką potrzebę i tylko w rzadkich przypadkach. – jfpoilpret

0

Uważam, że użycie Guice w graficznym interfejsie graficznym działa najlepiej w konfiguracji usługi.

Przy takim podejściu konieczne jest odpowiednie skonfigurowanie zakresów interakcji, aby móc odpowiednio wstrzykiwać obiekty domen użytkownika wybrane w interfejsie GUI do usług.

Zamiast tego można uzyskać dostęp do danych wyboru z usługi, która jest wstrzykiwana jako usługa pojedyncza do innych usług, które wymagają danych wyboru.

SelectionService może być coś takiego

public interface SelectionService { 

    Product getSelectedProduct(); 

    // ... 

} 

W rozwoju Web GUI masz na przykład sesji i zakresu żądania. Uważam, że ustalanie zasięgów jest trudniejsze w programowaniu Desktop GUI, więc wybrałbym DI dla usług singletonowych i okablowania statycznych komponentów GUI i ręcznego tworzenia instancji dla wszystkich pozostałych.

A jeśli chcesz, aby dane wyboru były dostępne jako usługa, może pomóc fragment kodu.

0

Zależy od tego, co rozumiemy przez "GUI".

Nie używałbym DI dla JSPs, ale chciałbym używać kontrolerów, które oddziałują z nimi. Uważam kontrolerów za część interfejsu użytkownika. Wstrzykuję weryfikatory, twórców map i usługi, które są im potrzebne do wypełniania żądań i tworzenia odpowiedzi.

Jeśli się zgadzasz, to DI jest odpowiednie dla warstwy widoku.

1

A composite GUI może oczywiście skorzystać z DI. Musisz jednak zachować dogmatyczność w utrzymywaniu orientacji kompozytowej. Każde bezpośrednie sprzężenie między elementami interfejsu spowoduje wiele bólów głowy.

1

Problemem jest to, że nie może wiedzieć Guice co wyrobów wybrałem w tabeli , więc nie może wiedzieć, co wstrzykiwać w EditProductDialog.

Skorzystaj z wtrysku zależności dla zależności, które mogą zostać rozwiązane przez Guice (gdy aplikacja jest uruchomiona). Użyj argumentów metody do ustawienia dowolnego stanu usług, który jest określony przez logikę aplikacji i dlatego jest znany tylko później, w czasie wykonywania.

W tym konkretnym przypadku kod, który decyduje o tym, który produkt ma zostać wyświetlony (prawdopodobnie ProductFrame, który zna zaznaczenie w tabeli), wywołałby w oknie dialogowym metodę SetProduct przed jej wyświetleniem.

Powiązane problemy