MVC - Controller verbessern

Status
Nicht offen für weitere Antworten.

ttt@web.de

Mitglied
Hallo,

ich habe beim MVC etwas Probleme, nämlich dabei die Ereignisse aus der View an den Controller weiter zu geben.
Die View enthält alle GUI Elemente, Labels, Buttons… beim klicken auf ein Button soll nun das Ereignis vom Controller verarbeitet und geg. Falls das Model verändert werden.

So, bisher hab ich es im Controller immer so gemacht:
View registriert sich beim Controller (mittels this) somit werden alle Ereignisse wie folgt ausgewertet.

public void actionPerformed(ActionEvent evt)
Code:
{
    if (evt.getActionCommand().equals("Add")) {...}
    else if (evt.getActionCommand().qeuals("Remove")...
}

aber das mit den String-Vergleichen ist nicht wirklich schön. Wie kann man das unter SWT besser machen?

LG



L-ectron-X hat diesen Beitrag am 29.05.2008 um 19:14 Uhr editiert.
Code-Tags eingefügt.
 

ttt@web.de

Mitglied
Wie ist die folgende Lösung:

1. Lösung View und Controller gemischt
Ich verbinde die View und den Controller in einer Datei.

Code:
Button addData = new Button(dataComposite, SWT.PUSH);
addData.setBounds(100,28,80,20);
addData.setText("OK");
addData.addSelectionListener(new SelectionListener()
{
   public void widgetDefaultSelected(SelectionEvent e)
   {
        DataModel model = DataModel.getInstance();
        PersonData data = new PersonData();
        data.setName(InputView.this.nameText.getText());
        data.setSurname(InputView.this.surnameText.getText());
        data.setTitle(InputView.this.titleText.getText());
        model.addPerson(data);                                              
   }

dadurch hab ich zwar keine sooo saubere Trennung, erscheint mir aber dennoch eine gute Lösung zu sein.

2. Lösung View
Alternativ könnte man auch folgendes machen View.java:

Code:
addData.addSelectionListener(new SelectionListener()
{
    public void widgetDefaultSelected(SelectionEvent e)
    {
         Controller... 
         Controller.daddData(...);
    }

2. Lösung Controller
und in einer separaten Datei Controller.java:

Code:
addData()
{
     DataModel model = DataModel.getInstance();
     PersonData data = new PersonData();
     data.setName(InputView.this.nameText.getText());
     data.setSurname(InputView.this.surnameText.getText());
     data.setTitle(InputView.this.titleText.getText());
     model.addPerson(data);  
}



L-ectron-X hat diesen Beitrag am 29.05.2008 um 19:15 Uhr editiert.
Code-Tags eingefügt.
 
G

Gast

Gast
Also so ohne Zusammenhang finde ich deine Aussagen jetzt etwas verwirrend aber ich denke dir geht es darum im Controller rauszufinden auf welche Aktion du reagieren sollst. Richtig?

Also ich denke es gibt 3 verschiedene Ansätze:

1) Der ActionCommand-String-Vergleich-Ansatz:
Diesen hast du oben beschrieben. Ich finde ihn persönlich nicht so toll und hab ihn erst einmal benutzt.

2) Globale-GUI-Elemente-Vergleich:
Wenn du View und Controller in einer Klasse hast, könntest du global deine GUI-Elemente deklarieren (also auf Klassenebene) und dann per equal vergleichen. Also etwa so:

Code:
public class View implements ActionListener {
private JTextField textfeld1;
private JTextField textfeld2;

public View() {
   textfeld1 = new JTextField();
   textfeld2 = new JTextField();
   textfeld1.addActionListener(this);
   textfeld2.addActionListener(this);
}

public void actionPerformed(ActionEvent evt) {
if(evt.getSource().equals(textfeld1)) {
//hier passiert aktion 1

}else if(evt.getSource().equals(textfeld2)) {
//hier passiert aktion 2

}
}

3) Für jede Aktion eine Klasse
Diese Methode bevorzuge ich. Zuerstmal hat man eine eindeutige Struktur und zweitens kann man die Klassen oftmals mehrfach verwenden.

Code:
public class View {
public View() {
   textfeld1 = new JTextField();
   textfeld2 = new JTextField();
   textfeld1.addActionListener(new ActionClass1());
   textfeld2.addActionListener(new ActionClass2());
}}

public class ActionClass1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
//hier passiert Aktion 1
}}

public class ActionClass2 implements ActionListener {
public void actionPerformed(ActionEvent e) {
//hier passiert Aktion 2
}}

Der Quellcode wurde von mir gerade hier im Forum geschrieben und wurde nicht getestet!!!

Ich hoffe es hilft dir.


L-ectron-X hat diesen Beitrag am 29.05.2008 um 19:17 Uhr editiert.
Code-Tags eingefügt.
 

ttt@web.de

Mitglied
Krondor hat gesagt.:
hmmm... ich war das... nächstes mal melde ich mich an ;)

Vielen Dank, dachte schon da kommt keine Antwort mehr...

Also ich verwende SWT, da gibts kein ActionListener sondern nur SelectionListener...

meine Fragen sind jetzt:

1. Der folgende Code stellt den Controller dar, nicht wahr?
Code:
public class ActionClass1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
//hier passiert Aktion 1
}}

public class ActionClass2 implements ActionListener {
public void actionPerformed(ActionEvent e) {
//hier passiert Aktion 2
}}


2. Wie trennst du den Code? Behälst du diesen in der selben Datei (als anonyme Klasse) oder machst du extra Klassen? Was ist denn besser?



L-ectron-X hat diesen Beitrag am 29.05.2008 um 19:19 Uhr editiert.
Code-Tags eingefügt.
 

Krondor

Aktives Mitglied
1) Ja das sind die Controller Klassen. Jede steht für eine bestimmte Aktion.
2) Also normalerweise mache ich separate Klassen, da man dann ganz einfach diese Aktion auch an anderen Stellen der Software verwenden kann. Diese Klassen sollten dann auch immer eine Referenz auf das Model übergeben bekommen (außer du benutzt Singleton), so dass du Zugriff auf die Daten des Models hast, welche du verändern möchtest.

Du kannst natürlich auch anonyme Klassen verwenden. Jedoch solltest du dann eine Oberklasse "Aktion" (oder so) erstellen von welcher die anonymen Klassen erben. Diese Oberklasse sollte den Listener implementieren und das Model übergeben bekommen (per Konstruktor, außer du benutzt Singleton), sonst hast du keinen Zugriff auf die Modeldaten.
 
G

Guest

Gast
Krondor hat gesagt.:
Diese Klassen sollten dann auch immer eine Referenz auf das Model übergeben bekommen (außer du benutzt Singleton), so dass du Zugriff auf die Daten des Models hast, welche du verändern möchtest.

Dazu hätte ich eine Frage:

Wenn du den Controller-Klassen eine Referenz auf das Model übergibst, dann ist das Programm doch sehr stark gekoppelt.
Denn: Um auf das Model zuzugreifen, musst du dem Controller eine Referenz des Objekts übergeben. Da die View aber den Controller erzeugt, muss auch die View das Model kennen, also sieht das IMHO so aus:

Model model = new Model();
View view = new View(model);

Dann in der View ein neues Controller Objekt erzeugt und das Model übergeben:
Controller controller = new Controller(model);




ODER

verstehe ich dich da gerade falsch und du denkst dir das so:
Code:
public class Main {


	public static void main(String[] args) {
		Model model = new Model();
		
		Controller controller = new Controller(model);
		
		View view = new View(controller);
	}
}
 

HLX

Top Contributor
Anonymous hat gesagt.:
Wenn du den Controller-Klassen eine Referenz auf das Model übergibst, dann ist das Programm doch sehr stark gekoppelt.
Denn: Um auf das Model zuzugreifen, musst du dem Controller eine Referenz des Objekts übergeben. Da die View aber den Controller erzeugt, muss auch die View das Model kennen, also sieht das IMHO so aus:
Der View erzeugt den Controller? :noe:

Eher umgekehrt - sonst wär´s ja kein Controller. :wink:

Controller übernehmen alle anwendungssteuernden Aufgaben. Innerhalb der Controller werden (falls keine Singletons eingesetzt werden) auch die Model-Objekte erzeugt. Ob das nun der AnwendungsController oder der Controller eines Views macht oder einer dazwischen, hängt vom Anwendungsfall ab. Je früher die Erzeugung erfolgt bzw. je vielseitiger eine Model-Komponente eingesetzt wird, desto öfter wird sie dabei an andere Controller übergeben.
 

Krondor

Aktives Mitglied
Der View erzeugt den Controller? noe.gif

Eher umgekehrt - sonst wär´s ja kein Controller. icon_wink.gif

Naja es gibt wohl zwei verschiedene Arten von Controllern.
Controller welche eine View aufrufen und Controller welche von der View aufgerufen werden um eine Aktion im Model auszuführen.

Wenn du den Controller-Klassen eine Referenz auf das Model übergibst, dann ist das Programm doch sehr stark gekoppelt.

Kommt darauf an wie man es umsetzt. Im Normalfall schreibt man sich eine Superklasse "ActionModel" (oder wie auch immer man die nennen möchte). Solch ein Model muss halt an eine Action übergeben werden. Wie willst du sonst den Zusammenhang zwischen Controller und Model herstellen? Als Alternative ist halt Singleton zu nennen bei dem man über eine static Funktion auf das einzige Model-Objekt zugreifen kann.
Davon abgesehen kannst du deine Controller ja auch nicht so schreiben, dass sie mit JEDER Klasse umgehen können. Also muss der Controller auch eine bestimmte Struktur übergeben bekommen mit welcher er klar kommt. Dies kann beispielsweise auch eine klasse sein, welche ein bestimmtes Interface implementiert.

Eine Kopplung bzw. Verzweigung der Klassen kannst du aber so oder so nicht verhindern.
Du könntest es höchstens per Singleton minimieren aber auch dort musst du halt dann von dem Controller auf das Model zugreifen.

Sorry das ich erst soviel später antworte. Hatte vorher keine Zeit.

Falls ich nachher ein paar Minuten Zeit hab schreibe ich dir mal ne Beispielanwendung die du testen kannst.
 

byte

Top Contributor
Krondor hat gesagt.:
Eine Kopplung bzw. Verzweigung der Klassen kannst du aber so oder so nicht verhindern.
Du könntest es höchstens per Singleton minimieren aber auch dort musst du halt dann von dem Controller auf das Model zugreifen.
Ja, aber trotzdem ist die Frage nach dem "wie" entscheidend. Es mag zunächst "einfacher" erscheinen, wenn die View seinen Controller kennt und aufruft. Es ist aber wesentlich sinnvoller, wenn es umgekehrt ist, d.h. der Controller kennt seine View, die View selber ist "dumm" (Stichwort: Passive View).

Ich wende folgendes Konzept an: Interface View für komplexe GUI-Komponenten und Interface ViewController für den Controller genau einer View. Wenn eine View aus weiteren komplexen GUI-Komponenten besteht, so bekommen diese einen eigenen ViewController. Jeder ViewController kann also also viele Kind-ViewController besitzen. Der Controller kennt seine View und registriert etwaige Listener und setzt die Modelle (TableModel, TreeModel, usw).
Die Erzeugung läuft dann wie folgt: Ein (Root-) ViewController erzeugt zunächst seine Kind-ViewController, dann wird die View erzeugt. Etwaige "Unterviews" zum Erzeugen einer View bekommt man dabei über den entsprechenden Kind-ViewController.
Auf diese Weise ist Logik und Präsentation getrennt und man hat wiederverwendbare Komponenten. Die Views können bei den Unittests ignoriert werden. Der Zustand von Root-ViewControllern (und seinen Kindern) kann bei Bedarf persistiert werden. Uvm.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
O Service oder Controller Allgemeine Java-Themen 6
M Best Practice MVC- Was gehört in den Controller? Allgemeine Java-Themen 1
K Java FX Zu startenden FXML-Controller per Parameter wählen Allgemeine Java-Themen 2
X Controller pro Frame? Allgemeine Java-Themen 8
K GUI-Entwicklung - Dispose, enabling und mehrere Controller Allgemeine Java-Themen 1
H Model-View-Controller Fail? Allgemeine Java-Themen 31
M Model View Controller Entwurfsmuster! Allgemeine Java-Themen 11
D GUI-Controller Konzept Allgemeine Java-Themen 6
J Model View Controller Architektur Allgemeine Java-Themen 6
O Formularinhalte der jsp in Controller nicht greifbar Allgemeine Java-Themen 2
B MVC: controller in unabhängigen thread von der view starten (gui friert ein) Allgemeine Java-Themen 5
Y Exception Handling - Controller-Businesslogik-Persitenz Allgemeine Java-Themen 7
G Problem mit MVC-Pattern (Controller als anonyme Unterklasse) Allgemeine Java-Themen 2
N XInput API (DLL für XBox 360 Controller) mit Java benutzen? Allgemeine Java-Themen 3
K MVC - Kommunikation Controller <> Gui Allgemeine Java-Themen 5
D Controller für GUI (MVC) Allgemeine Java-Themen 6
M Klasse durch Klassen Aufteilung verbessern, aber wo? Allgemeine Java-Themen 1
H Performance einer Monte-Carlo-Simulation verbessern Allgemeine Java-Themen 6
Scream_ilias brute force methode verbessern? Allgemeine Java-Themen 6
J Threads verbessern die Performance NICHT ? Allgemeine Java-Themen 8
A Java Programm verbessern/vereinfachen Allgemeine Java-Themen 20
H Javakenntnisse verbessern Allgemeine Java-Themen 5
M Berechnung verbessern Allgemeine Java-Themen 8
A Salt Erstellung verbessern Allgemeine Java-Themen 7
V Kollisionserkennung beschleunigen/verbessern? :) Allgemeine Java-Themen 14
J java vnc client verbessern: KeyEvent.VK_ALT keine Wirkung? Allgemeine Java-Themen 12
T Algorithmus verbessern Allgemeine Java-Themen 10
C JTable verbessern Allgemeine Java-Themen 6

Ähnliche Java Themen

Neue Themen


Oben