MVC MVC engl ModelView Controller deutsch Modell PrsentationSteuerung

  • Slides: 33
Download presentation
MVC

MVC

MVC (engl: Model-View. Controller, deutsch: Modell. Präsentation-Steuerung) ist ein Entwurfsmuster zur Strukturierung von Software,

MVC (engl: Model-View. Controller, deutsch: Modell. Präsentation-Steuerung) ist ein Entwurfsmuster zur Strukturierung von Software, das eine spätere Änderung erleichtert und eine Wiederverwendbarkeit der einzelnen Komponenten ermöglicht.

Wenn z. B. die Daten in der Klasse View anders dargestellt werden sollen, muß

Wenn z. B. die Daten in der Klasse View anders dargestellt werden sollen, muß nur die Klasse View, aber nicht die Klasse Controller und die Klasse Model geändert (angepaßt) werden.

Zuständigkeiten:

Zuständigkeiten:

Model: Enthält die darzustellenden Daten und die zugehörigen Methoden. Model ist von View und

Model: Enthält die darzustellenden Daten und die zugehörigen Methoden. Model ist von View und Controller unabhängig.

View: stellt die Daten des Models dar

View: stellt die Daten des Models dar

Controller: nimmt die Anwendereingaben (z. B. Mausklick auf Button "+") entgegen und verändert dementsprechend

Controller: nimmt die Anwendereingaben (z. B. Mausklick auf Button "+") entgegen und verändert dementsprechend die Daten (Summenbildung) des Modells (mit Hilfe der Methoden des Models). Im Controller steckt die Logik der Reaktion auf die Eingabe.

WICHTIG: die Aufteilung der Aufgaben von M, V und C sind nicht 100% eindeutig

WICHTIG: die Aufteilung der Aufgaben von M, V und C sind nicht 100% eindeutig geregelt und deshalb etwas "interpretierbar". Das gibt Anlaß zu Diskussionen. Siehe Internet-Diskussionen, wie z. B: http: //www. flashforum. de/forum/softwarearchitektur-undentwurfsmuster/wieder-einmal-mvc-222602. html

Ereignis View Controller Ereignis Model damit das Ereignis eingefangen werden kann, muß aus dem

Ereignis View Controller Ereignis Model damit das Ereignis eingefangen werden kann, muß aus dem Controller eine Wanze gemacht werden. damit das Ereignis eingefangen werden kann, muß aus der View eine Wanze gemacht werden. Schwarze, durchgezogene Linien bedeuten Assoziationen, rote, gestrichelte Linien bedeuten Events (Ereignisse).

E(ingabe) V(erarbeitung) A(usgabe) Tastatur / Maus Controller A View E Model V Schwarze, durchgezogene

E(ingabe) V(erarbeitung) A(usgabe) Tastatur / Maus Controller A View E Model V Schwarze, durchgezogene Linien bedeuten Assoziationen, rote, gestrichelte Linien bedeuten Events (Ereignisse).

Bevor es hier weiter abstrakt zugeht, soll MVC an einem Beispiel erklärt werden:

Bevor es hier weiter abstrakt zugeht, soll MVC an einem Beispiel erklärt werden:

AUFGABE: Erstellen Sie einen Taschenrechner, der genau ein Textfeld hat und der nur addieren

AUFGABE: Erstellen Sie einen Taschenrechner, der genau ein Textfeld hat und der nur addieren kann. Er soll genau die 2 Buttons = und + haben. Implementieren Sie u. a. die Klassen Controller, …

View, Model, wobei in Model die mathematischen Berechnungen, in View die GUI und im

View, Model, wobei in Model die mathematischen Berechnungen, in View die GUI und im Controller die Steuerung gemacht werden. Hier das UML. . .

TRController - tr. View : TRView - tr. Model : TRModel - speicherwert :

TRController - tr. View : TRView - tr. Model : TRModel - speicherwert : double schwarzer Pfeil: Assoziation roter, gestrichelter geschwungener Pfeil: zeigt vom Ereignis (fire) zur Wanze (Lauscher)

TRController - tr. View : TRView - tr. Model : TRModel - speicherwert :

TRController - tr. View : TRView - tr. Model : TRModel - speicherwert : double Anwender feuert (z. B. durch Eingabe) in der View. Einfangende Methode (der Wanze) im Controller verändert Daten im Model feuert (weil Daten im Model geändert wurden). Einfangende Methode (der Wanze) in der View veranlaßt Bildschirmausgabe.

TRController - tr. View : TRView - tr. Model : TRModel - speicherwert :

TRController - tr. View : TRView - tr. Model : TRModel - speicherwert : double Durch das Klicken eines Buttons (= oder +) in der View wird "gefeuert". Dadurch werden in der einfangenden Methode des Controllers die Daten (das Attribut "speicherwert") in Empfang genommen und ins Modell weitergleitet (und dort verarbeitet). Diese Änderung veranlaßt das Model zu feuern. Dadurch wird in der einfangenden Methode der View die Daten (das Attribut "speicherwert") des Models ausgelesen und auf dem Bildschirm ausgegeben.

TRController - tr. View : TRView - tr. Model : TRModel - speicherwert :

TRController - tr. View : TRView - tr. Model : TRModel - speicherwert : double Wie siehe eine Kette der Informationsverarbeitung aus , d. h: Wer feuert, welche Wanzen treten dann in Aktion und auf welche Daten greifen diese dann zu?

TRController - tr. View : TRView - tr. Model : TRModel - speicherwert :

TRController - tr. View : TRView - tr. Model : TRModel - speicherwert : double Button wird betätigt --> Feuer Einfangende Methode des Controllers verändert die Daten ("speicherwert") des Model, also. . . --> Feuer Einfangende Methode der View greift auf die Daten ("speicherwert") des Model zu (für Bildschirmausgabe).

Implementieren Sie - soweit dies mit Ihrem bisherigen Wissen möglich ist M, V und

Implementieren Sie - soweit dies mit Ihrem bisherigen Wissen möglich ist M, V und C des obigen Taschenrechners.

package taschenrechnermvc 15; import import java. awt. *; java. awt. event. Action. Event; java.

package taschenrechnermvc 15; import import java. awt. *; java. awt. event. Action. Event; java. awt. event. Action. Listener; java. util. Observable; java. util. Observer; javax. swing. *;

public class Startklasse. Taschenrechner. MVC 15 { public static void main(String[] args) { TRController

public class Startklasse. Taschenrechner. MVC 15 { public static void main(String[] args) { TRController tr. Controller = new TRController(); TRView tr. View = new TRView(); TRModel tr. Model = new TRModel(); // Verlinken von M, V und C tr. Controller. set. Tr. Model(tr. Model); tr. Controller. set. Tr. View(tr. View); tr. View. set. Tr. Model(tr. Model); // "Prozeße" starten tr. Model. Wanze. Anbringen(tr. View); tr. View. Wanze. Anbringen(tr. Controller); } }

class TRModel extends Observable { private double speicherwert; public TRModel() { speicherwert=0; } public

class TRModel extends Observable { private double speicherwert; public TRModel() { speicherwert=0; } public double get. Speicherwert(){ return speicherwert; }

public void set. Speicherwert(double wert){ Falls eine andere View an das Model speicherwert=wert; angebracht

public void set. Speicherwert(double wert){ Falls eine andere View an das Model speicherwert=wert; angebracht soll, müsste diese // Dem Model das Feuernwerden ermöglichen set. Changed(); Methode geändert werden, d, h. die Klasse Model müsste geändert werden. Um dies notify. Observers(); zu vermeiden, wäre z. B. folgendes } sinnvoll: public void addiere. Dazu(double wert) { speicherwert=speicherwert+wert; // Dem Model das Feuern ermöglichen set. Changed(); notify. Observers(); } public void Wanze. Anbringen(TRView tr. View) { this. add. Observer(tr. View); } }

public void set. Speicherwert(double wert){ speicherwert=wert; // Dem Model das Feuern ermöglichen set. Changed();

public void set. Speicherwert(double wert){ speicherwert=wert; // Dem Model das Feuern ermöglichen set. Changed(); notify. Observers(); } public void addiere. Dazu(double wert) { speicherwert=speicherwert+wert; // Dem Model das Feuern ermöglichen set. Changed(); notify. Observers(); } public void Wanze. Anbringen(Observer obs) { this. add. Observer(obs); } }

Bemerkung: Der Typ TRView sollte weder für Attribute noch für lokale Variablen oder Parameter

Bemerkung: Der Typ TRView sollte weder für Attribute noch für lokale Variablen oder Parameter in der Model-Klasse auftauchen. Hintergrund ist der, dass das Model theoretisch ohne Vorhandensein irgendwelcher View-Klassen compiliert werden können soll.

class TRView extends JFrame implements Observer { private TRModel tr. Model; private JButton button.

class TRView extends JFrame implements Observer { private TRModel tr. Model; private JButton button. Plus; private JButton button. Gleich; private JText. Field tfd. Zahl; public TRView(){ buttons. Anbringen(); } public TRModel get. Tr. Model() { return tr. Model; } public void set. Tr. Model(TRModel tr. Model) { this. tr. Model = tr. Model; }

public String get. JText. Field() { return tfd. Zahl. get. Text(); } public void

public String get. JText. Field() { return tfd. Zahl. get. Text(); } public void set. JText. Field(String str) { this. tfd. Zahl. set. Text(str); } public void buttons. Anbringen() { button. Plus = new JButton("+"); button. Gleich = new JButton("="); tfd. Zahl = new JText. Field("hier Zahl eingeben", 30);

// Beim Anklicken dieses Buttons wird ein Ereignis// objekt geworfen, das durch den String

// Beim Anklicken dieses Buttons wird ein Ereignis// objekt geworfen, das durch den String "btn+" // identifiziert wird. button. Plus. set. Action. Command("btn+"); // siehe oben. . . button. Gleich. set. Action. Command("btn="); get. Content. Pane(). add(button. Plus, Border. Layout. EAST); get. Content. Pane(). add(button. Gleich, Border. Layout. WEST); get. Content. Pane(). add(tfd. Zahl, Border. Layout. CENTER); this. set. Size(200, 100); set. Default. Close. Operation(JFrame. EXIT_ON_CLOSE); this. set. Visible(true); }

public void Wanze. Anbringen(TRController t. RController) { button. Plus. add. Action. Listener(t. RController); button.

public void Wanze. Anbringen(TRController t. RController) { button. Plus. add. Action. Listener(t. RController); button. Gleich. add. Action. Listener(t. RController); } // wird automatisch aufgerufen (ereigniseinfangende // Methode), wenn in TRModel ein Ereignisobjekt // geworfen wird. public void update(Observable m, Object o) { if (m == tr. Model) { set. JText. Field(String. value. Of (tr. Model. get. Speicherwert())); } } }

class TRController implements Action. Listener{ private TRView tr. View; private TRModel tr. Model; public

class TRController implements Action. Listener{ private TRView tr. View; private TRModel tr. Model; public TRController() { } public TRView get. TRView() { return tr. View; } public TRView get. Tr. View() { return tr. View; } public void set. Tr. View(TRView tr. View) { this. tr. View = tr. View; }

public TRModel get. Tr. Model() { return tr. Model; } public void set. Tr.

public TRModel get. Tr. Model() { return tr. Model; } public void set. Tr. Model(TRModel tr. Model) { this. tr. Model = tr. Model; } // // // wird automatisch aufgerufen (ereigniseinfangende Methode), wenn in TRView ein Ereignisobjekt geworfen wird (Button angeklickt). siehe nächste Folie

public void action. Performed(Action. Event ae){ String str; str=ae. get. Action. Command(); // Ereignis

public void action. Performed(Action. Event ae){ String str; str=ae. get. Action. Command(); // Ereignis wird identifiziert if(str. equals("btn+")){ double wert = Double. value. Of(tr. View. get. JText. Field()); tr. Model. set. Speicherwert(wert); } if(str. equals("btn=")){ double wert = Double. value. Of(tr. View. get. JText. Field()); tr. Model. addiere. Dazu(wert); } } }

AUFGABE: Ergänzen Sie den Taschenrechner um die Funktionen eines handelsüblichen Taschenrechners.

AUFGABE: Ergänzen Sie den Taschenrechner um die Funktionen eines handelsüblichen Taschenrechners.