Witam wszystkich. Mam do napisania mały program w javie (kilka widoków, dużo obliczeń). Zależy mi na tym abym mógł ten program w przyszłości śmiało pokazać potencjalnemu pracodawcy i zależy mi na tym aby wykorzystać klasyczne podejście MVC. Wiecznie w każdym języku programowania mam problem z MVC i chciałbym rozwiać swoje wątpliwości przynajmniej w Javie. Dużo czytałem na temat MVC i widziałem różne podejścia do tego. Chciałbym napisać coś swojego co będzie w 100% zgadzało się z MVC ale mam kilka wątpliwości i pytań. Może zacznę od mojej przykładowej implementacji.
W głównej klasie programu mam:
public void run() {
Model model = new Model();
View view = new View(model);
Controller controller = new Controller(model, view);
view.setVisible(true);
}
W Modelu standardowo mam całą strukturę danych. Tu nie będę wchodził w szczegóły.
W Widoku mam zbudowane cale gui programu. Na potrzeby mojego programu podzieliłem go na kilka klas widoku ale wszystkie te klasy są dostępne w widoku. Wygląda to mniej więcej tak:
public class View extends JFrame {
private Model model;
private MainView firstView;
private SettingsView settingsView;
private BottomBar bottomBar;
private JButton button;
// i tak dalej..
}
Zaznaczę tu tylko ze w Widoku nie ustawiam żadnych listenerów... nie wiem czy to dobrze... później wrócę do tego tematu.
W kontrolerze mam dostęp do modelu i widoku. Widok wie jak ma wyglądać. Model zawiera dane. W kontrolerze pozostaje do napisania obsługa zdarzeń/poleceń idących od użytkownika poprzez Widok. W związku z tym rozumiem to tak że mając dostęp do modelu i widoku tworze cały kod ustawiając odpowiednio listenery dla komponentów w widoku. Wygląda to mniej więcej tak:
public Controller(Model model, View widok) {
instance = this;
this.model = model;
this.view = widok;
init();
}
private void init() {
/////////////////////////////////////////////
/////////////// Set listeners ///////////////
/////////////////////////////////////////////
// Menu listener
view.setMenu(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if ("finish".equals(e.getActionCommand())) {
if (view.showCloseDialog() == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
}
});
// Progress bar
view.getBottomBar.getProgressBar.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent arg0) {
view.getBottomBar.getProgressBar.setString("Warunek konca: " + view.bottomBar.progressBar.getValue() + "%");
}
});
// i tak dalej..
// Set status
view.getBottomBar.setStatusLabel(StatusEnum.ADD_BASE_POINT);
// Set default values
setCalculationMode(CalculationModeEnum.SLOW);
// i tak dalej
}
}
Jak widać powyżej z racji że mam dostęp do widoku i modelu, ustawiam wszelkie niezbędne listenery czyli tak właściwie obsługę zdarzeń które triggeruje user poprzez klikanie po gui.
- Czy takie podejście jest poprawne mając na uwadze klasyczne MVC? Czy jednak listenery powinny być ustawione w widoku w taki sposób że wywołują metodę w kontrolerze która zawiera obsługę zdarzenia czyli tak na prawdę dokładnie to samo co jest w definicji aktualnych listenerów.
- Jak to się ma do MVP? Czy czasem kontroler nie pełni tutaj tak na prawdę roli prezentera?
- Czy w klasycznym MVC gdy chce zmienić coś w modelu i jednocześnie widok powinien również tą zmianę pokazać czy poprawnym podejściem jest zmienić w kontrolerze model a następnie wywołać metodę update w widoku która pokaże zmianę tego modelu czy jednak zamiast tego kontroler powinien zmienić tylko model a model poprzez Obserwera powiadomić Widok o zmianie w modelu i wtedy Widok powinien automatycznie się odświeżyć? (Odnoszę wrażenie że tutaj właśnie występuje ta kluczowa różnica pomiędzy MVC i MVP).
- W przypadku większych programów dobrym podejściem jest tworzenie więcej kontrolerów (mini kontrolerów) które zajmują się mniejszymi częściami programu?