# MVC: 2 Varianten



## Christian435 (18. Mrz 2007)

Meine Frage bezieht sich auf den Text unter http://java.sun.com/developer/technicalArticles/javase/mvc/ 
Dort werden zwei Varianten für das MVC Design Pattern vorgestellt.


relevante Textstellen:

Figure1. A Common MVC Implementation
Figure 4. An MVC Design Placing the Controller Between the Model and the View


<quote>
Issues With Application Design


Once the application is up and running, you immediately run into a problem. Consider the following chain of events:
One of the Swing components in the view receives a change, presumably from the user action.
The appropriate controller method is called.
The model is updated. It notifies the controller of its property change.
The view receives a change event from the controller and attempts to reset the value of the appropriate Swing components.
The appropriate controller method is called, and the model is updated again.

At this point, any of three different scenarios can occur, depending on what Swing component you use and how robust your model is. 
The Swing component that prompted the initial change refuses to update itself the second time, noting that its property state cannot be updated again while it is in the process of notifying listeners of the initial state change. This primarily occurs when you use Swing text components. 
The model notes that the value of the second update matches that of the first, its current value, and refuses to send a change notification. This is always a safe programming practice, and it automatically occurs if you use the PropertyChangeSupport class provided in the java.beans package. However, it does not keep the model from receiving a redundant update. 
No safeguards are in place on either the model or the Swing component, and the program enters an infinite loop.
</quote>


Ich hatte zunächst gedacht, dass sich dieses Problem nur auf die "neue" Variante bezieht. Das Problem müsste doch aber auch bei der ersten MVC Variante auftauchen.

Beispiel: Ich habe ein einfaches Model, das den Zustand true oder false haben kann. Aus irgendeinem Grund habe ich zwei Views, also zwei Fenster, mit einer Checkbox die diesen Zustand repräsentiert (beide beziehen sich auf die selbe Instanz des Models). 


-----------------
Variante 1 ("ursprüngliches MVC"): 

Veränderung (checkbos -> checked) in Fenster 1 wird mittels Listener über den Controller in das Model gespeichert. 

checkBox.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent e) {
//hier Controller aufrufen, der den Zustand im Model ändert
}
});


Das Model (Observable) informiert die Views (Obeserver). Diese verändern jetzt den Zustand der checkbox mit checkbox.setSelected(true) [obwohl das im ersten Fenster nicht nötig wäre, da schon geschehen]. Dadurch wird ja wieder der Event für itemStateChanged aufgerufen..... -> Endlosschleife?

-----------------
In Variante 2 sowieso, wie der englische Text bespricht.


Die Bilder der beiden Varianten sind mir insofern nicht klar, da dort steht "User Gesture" bzw. "User Action" bei den Pfeilen in denen das View den Controller informiert......gibt es dazu etwa spezielle Listener die ein Update verhindern wenn eine Änderung vom Programm und nicht vom User hervorgerufen wurde...


Die Frage ist also, ob es einen Unterschied in Bezug auf dieses Endlosproblem gibt je nach dem welceh Variante des MVC ich benutze. Und überhaupt welche zu bevorzugen ist....bei Variante 2 werden View und Model ja etwas mehr getrennt, weshalb ich zu dieser Variante tendiere, sollten keinen Unterschied bei diesem Endlosproblem geben.


----------



## Gast (27. Mrz 2007)

Hi,
wie der Text schon ganz richtig sagt hängt alles davon ab, wie robust Du arbeitest. Das Problem ist nur ein mögliches Problem, das man im Hinterkopf behalten sollte/muss. Aber es ist natürlich nicht immer der Fall, dass dieses Problem eintritt.

Natürlich ist für beide Fälle eine Möglichkeit vorhanden, mit der man eine Endlosschleife erzeugen kann, in beiden Fällen wären sie aber auch sehr konstruiert. Der eigentliche Unterschied ist halt, dass bei der zweiten Variante sowohl Modell als auch View vom Controller verändert werden. 
Dadurch kann jetzt die View-Instanz nicht unterscheiden, ob eine Veränderung durch eine Benutzer-Interaktion oder durch den Vermittler/den Controller statt fand. Diese Möglichkeit gibt es nicht, wenn die View-Instanz selbst den Status des Modells abfragt. Für diesen Fall ist bekannt, dass es sich hier nicht um eine Aktion von außen handelt, der Controller würde also nicht benachrichtigt werden (worauf man natürlich achten muss!).

Genauso kann man aber auch in der zweiten Variante einfach diese Möglichkeit berücksichtigen und für die Benachrichtigung über Änderungen vom Controller andere Methoden zur Verfügung stellen, als bei Veränderungen von Außen.
Ein einfacher Weg diese Form von Schleife zu durchbrechen (der auch im Text erwähnt wurde) liegt darin, dass das Modell nur bei wirklicher Änderung (neuer Wert unterscheidet sich vom Alten) eine Benachrichtigung durchführt. Gleicht der neue Wert dem alten, so hat sich nichts geändert, was die Beobachter von Veränderungen nicht interessiert.


----------

