Nie mogę znaleźć lepszego rozwiązania mojego problemu. Mam kontroler widoku, który przedstawia listę elementów. Te elementy to modele, które mogą być instancjami B, C, D itp. I dziedziczyć po A. W tym kontrolerze widoku każdy element powinien przejść do innego ekranu aplikacji i przekazać niektóre dane, gdy użytkownik wybierze jeden z nich . Dwie alternatywy, które przychodzą mi do głowy to (zignoruj składnię, to nie jest konkretny język)
1) przełącznik (wiem, że jest do bani)
//inside the view controller
void onClickItem(int index) {
A a = items.get(index);
switch(a.type) {
case b:
B b = (B)a;
go to screen X;
x.v1 = b.v1; // fill X with b data
x.v2 = b.v2;
case c:
go to screen Y;
etc...
}
}
2) polimorfizm
//inside the view controller
void onClickItem(int index) {
A a = items.get(index);
Screen s = new (a.getDestinationScreen()); //ignore the syntax
s.v1 = a.v1; // fill s with information about A
s.v2 = a.v2;
show(s);
}
//inside B
Class getDestinationScreen(void) {
return Class(X);
}
//inside C
Class getDestinationScreen(void) {
return Class(Y);
}
Mój problem z rozwiązaniem 2 polega na tym, że ponieważ B, C, D itp. Są modelami, nie powinni wiedzieć o rzeczach związanych z wyświetlaniem. A może powinni w takim przypadku?
źródło
Bardziej komentarz niż odpowiedź, ale myślę, że to los. Albo Zobacz musi wiedzieć wszystko o modelu więc może wybrać ekran (przełącznik) lub model musi wiedzieć wszystko o widok więc to może wybrać ekran (polimorfizm). Myślę, że musisz wybrać to, co według ciebie będzie najprostsze w czasie; nie ma właściwej odpowiedzi na pytanie. (Mam nadzieję, że ktoś może udowodnić, że się mylę). Ja sam skłaniam się ku polimorfizmowi.
Wpadłem trochę na ten problem. Najbardziej irytującym przypadkiem była klasa Wędrowca, której przypadki wędrowały po mapie. Aby go narysować, albo wyświetlacz musiał wiedzieć o Wędrowcu, albo Wędrowiec musiał wiedzieć o wyświetlaczu. Problem polegał na tym, że pojawiły się dwa wyświetlacze. Ponieważ liczba różnych podklas Wędrowca była duża i stale rosła, umieściłem kod rysunkowy w podklasach Wędrowca. Oznaczało to, że każda duża klasa miała dokładnie jedną metodę, która musiała wiedzieć o Graphics2D i dokładnie jedną metodę, która musiała wiedzieć o Java3D. Brzydki.
Ostatecznie podzieliłem klasę, dając mi dwie równoległe struktury klas. Klasa Wanderer została uwolniona od wiedzy o grafice, ale klasa DrawWanderer nadal musiała wiedzieć więcej o Wanderer niż była przyzwoita i musiała wiedzieć o dwóch (i może więcej) zupełnie różnych środowiskach graficznych (Widoki). (Przypuszczam, że ten pomysł podziału klasy może być rodzajem odpowiedzi, ale tak naprawdę tylko zawiera problem.)
Myślę, że jest to bardzo ogólny i fundamentalny problem projektowania obiektowego.
źródło
Myślę, że przejście z przełącznikiem jest lepszą opcją niż przejście z polimorfizmem w tym przypadku.
Jest to dość prosta rzecz, więc nie sądzę, że musi to być nadmiernie skomplikowane przez zastosowanie polimorfizmu.
Chciałbym monetyzować w tym poście na blogu . Instrukcje przełączania niekoniecznie są brzydkie, o ile prawidłowo je używasz. A w twoim przypadku modele abstrakcyjne, takie jak te do użycia w kontrolerze, mogą być nadmierne i mogą przynosić niepożądane rezultaty. Jak naruszanie SRP.
źródło
Zgadzam się z tą troską. Niepokoi mnie również to, że obiekty, które znajdują się w comboboxie, będą się zachowywać. Nie jestem pewien, czy to „zła rzecz”, która nigdy tego nie zrobiła, wydaje mi się to po prostu nienaturalnym wyborem.
Poza tym nie wydaje się,
A
a jego podklasy są typem, z którym masz interesujący polimorfizm. Ciekawy typ jest w rzeczywistościScreen
. W tym przykładzieA
jest to tylko klasa, która przechowuje informacje w celu informowaniaScreen
stworzenia.Jeśli sprawisz, że combobox zawiera listę
a.type
zwrotów, wówczas instrukcja switch wydaje się bardziej naturalna. Jednak zamiast umieszczać go bezpośrednio w module obsługi zdarzeń kliknięcia, umieściłbym go wScreenFactory
. Następnie masz:Pozwala to przetestować zachowanie budowania ekranu i ładnie wyciąga niektóre funkcje z interfejsu użytkownika. Utrzymuje nienaruszone nakładanie warstw View. Być może upraszcza to twój projekt, jeśli to oznacza,
A
a podklasy można zwinąć wtype
flagę, którą zawierają.źródło