Hallo zusammen,
zu dem MVC Konzept kenne ich zwei Varianten
Fragen:
Variante_1 als Code-Beispiel:
Gruß
Sebastian
zu dem MVC Konzept kenne ich zwei Varianten
- Variante_1: Nach seiner Änderung (z. B. counter++) durch einen Controller, benachrichtigt das Model über model.modelChanged() alle angemeldeten Views, die ihre Anzeige aktualisieren.
- Variante_2: Nach seiner Änderung (z. B. counter++) durch einen Controller, benachrichtigt der Controller die View, die die Änderung angestoßen hat.
Fragen:
- Variante_1 erlaubt die Listener jeweils in ihrer View zu lassen und nicht in einer Controller Datei abzulegen, da jeder Listener auch nur in einer View verwendet wird. Ist von dieser (View+Listener)<->Model Struktur abzuraten?
- Variante_1 erlaubt das bilden von Schleifen, wenn eine View als reaktion auf eine model.modelChanged() das model ändert und wieder model.modelChanged() triggert. Lässt sich dies irgendwie unterbinden?
- Variante_2 scheint genau einen (vollgepackten)Controller zu brauchen, der alle Views kennt, und bei einer Änderung am Model jede View einzeln aktualisiert (wie würden sonst alle Views aktualisiert nach einer Model-änderung). Welchen Nutzen/Vorteil bietet dies gegenüber einer model.modelChanged() die alle Views triggert, woraufhin jede View sich selbst anpasst?
Variante_1 als Code-Beispiel:
Java:
package mainMethod;
import model.CounterModel;
import view.View_1;
import view.View_2;
public class TheMainMethod {
public static void main(String args[])
{
CounterModel model = CounterModel.getInstance();
View_1 firstView = new View_1();
View_2 secondView = new View_2();
}
}
Java:
package model;
public interface CounterModelInterface {
// The model calls this method when a model value changes to notify all views.
// All views implement this interface and can react to model changes by putting code in this method
public void modelChanged();
}
Java:
public class CounterModel implements CounterModelInterface{
private static CounterModel instance = null;
private int counter;
private ArrayList<CounterModelInterface> listeners;
// Singleton, only one model instance will ever exist
public static CounterModel getInstance()
{
if(instance == null)
{
instance = new CounterModel();
}
return instance;
}
private CounterModel()
{
counter = 0;
listeners = new ArrayList<CounterModelInterface>();
}
public void incrementCounter()
{
counter++;
modelChanged();
}
public int getCounter()
{
return counter;
}
// Notify all views that the model changed
@Override
public void modelChanged() {
for(CounterModelInterface listener : listeners)
{
listener.modelChanged();
}
}
public void addListener(CounterModelInterface listener)
{
listeners.add(listener);
}
}
Java:
package view;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import model.CounterModel;
import model.CounterModelInterface;
public class View_1 extends JFrame implements CounterModelInterface, ActionListener {
private JButton incrementButton;
private JLabel modelChangedLabel;
private CounterModel model;
public View_1()
{
// Init
super("View_1");
incrementButton = new JButton("Increment model counter");
modelChangedLabel = new JLabel("");
// Add listeners
incrementButton.addActionListener(this);
// Add elements
add(incrementButton);
add(modelChangedLabel);
// Add self to model as listener
model = CounterModel.getInstance();
model.addListener(this);
setSize(800,200);
setLayout(new GridLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
// When the model has changed a text is displayed to inform when the change happened
@Override
public void modelChanged() {
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date currentDate = new Date();
String currentDateString = sdfDate.format(currentDate);
modelChangedLabel.setText("The model was last changed at "+currentDateString);
}
// Button was pressed, increment the model counter
@Override
public void actionPerformed(ActionEvent e) {
model.incrementCounter();
}
}
Java:
package view;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import model.CounterModel;
import model.CounterModelInterface;
public class View_2 extends JFrame implements CounterModelInterface{
private JLabel modelCounterLabel;
private CounterModel model;
public View_2()
{
// Init
super("View_2");
modelCounterLabel = new JLabel("");
// Add elements
add(modelCounterLabel);
// Add self to model as listener
model = CounterModel.getInstance();
model.addListener(this);
setSize(300,200);
setLayout(new GridLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
// When the model has changed a text is displayed to show the counter value
@Override
public void modelChanged() {
modelCounterLabel.setText("Model counter: " + model.getCounter());
}
}
Gruß
Sebastian