Swing Baut die View die Modelebene auf oder wer?

Rudolf

Bekanntes Mitglied
Moinchen,

ich versuche ein Programm nach dem MVC zu bauen. Man soll ja Model von View trennen. Nun ist meine View ein Formular und die Model besteht aus drei Klassen, die jeweils Inhalte der Formulare erstellen. D.h. es wird ein Student, ein Business und ein Rating-Objekt erstellt, die jeweils Daten vom Formular haben.

Jetzt frage ich mich natürlich was echtes MVC bedeutet. Erstellt die View die jeweiligen Objekte aus dem Model, oder ist es eher MVC wenn die ganzen Strings an die Model übergeben werden und diese baut dann die Objekte zusammen. Für ein relativ großes Formular müsste man viele String Referenzen an eine Funktion übergeben. Das ist auch nicht schön.

Welche Vorgehensweise ist optimal?
 

JavaProfi

Aktives Mitglied
Grundsätzlich gehört IMO die ganze Geschäftslogik in den Controller.
Von der Geschäftslogik zu trennen sind Funktionalitäten, welche die Datenintegrität sicherstellen.
Diese gehören IMO in die Methoden des Models.
Die Manipulation der Daten im Model erfolgt ausschließlich über die Schnittstellen-Methoden des Models (z.B. getter- und setter-Methoden). Demnach würde ich Methoden zum Erzeugen und Entfernen von Objekten ebenso in das Model packen, denn die Objekte müssen ja sauber in die Datenstruktur (z. B. eine LinkedList) des Modells "eingehängt" werden. Das Anstoßen der Methoden zum Erzeugen der Objekte des Datenmodells erfolgt dann wiederum aus dem Controller heraus.

Die View beobachtet das Model. Eine View liest nur Daten aus dem Model, wenn das Model die View über Datenänderungen, die die View betreffen benachrichtigt. Das bedeutet, du benötigst in der View eine Funktionalität die auf notify()-Aufrufe des Models reagiert und aus der update()-Methode des Views angestoßen wird.

Der Controller reagiert auf die UserEvents und greift schreibend und lesend auf das Datenmodell zu. Der Controller beinhaltet IMO daher die Listener-Klassen (ich realisiere diese i.d.R. als innere Klassen, aber das ist sicher Geschmacksache) manipuliert die Daten im Datenmodell einerseits und manipuliert das "Verhalten" der GUI andererseits.
Unter Verhalten meine ich z.B. ob Komponenten enabled oder visible sind usw.

Wer baut das Model auf?
Nun ja, ich halte es in der Regel so, dass ich zuerst das Model (z. B. in der main-Methode der Applikation) instanziere. Dann instanziere ich die View und übergebe dem Konstruktor eine Referenz auf das Model. Als letztes instanziere ich den Controller und übergebe dem Konstruktor des Controllers Referenzen auf das Model und View.

Gruß
JP
 
Zuletzt bearbeitet:

Rudolf

Bekanntes Mitglied
Erstmal danke für deinen ausführlichen Beitrag, aber ich bin mir unsicher, ob der Kern des Problems deutlich geworden ist. Ich habe daher ein kleines Codebeispiel programmiert, das das Problem verdeutlichen soll. Für die Erklärungen sind auf die Kommentare im Code zu achten.

Java:
import java.util.HashSet;
import java.util.Set;

import javax.swing.JPanel;
import javax.swing.JTextField;


public class MVC {
	public static void main(final String[] args) {
		new Controller();
	}
}

class Controller {
	public Controller() {
		final Model model = new Model();
		final View view = new View(model);
		model.register(view);
	}
}

class Model {
	Set<Observer> ovservers = new HashSet<>();

	public void register(final View view) {
		ovservers.add(view);

	}

	void notfiyObs(final Event event) {
		for (final Observer o : ovservers) {
			o.update(event);
		}
	}

	public void handle(final String text1, final String text2) {
		final Student student = new Student(text1);
		final Business business = new Business(text2);
	}

	public void handle(final Student student, final Business business) {
		// TODO Auto-generated method stub

	}

}

class Student {

	public Student(final String text) {
		// TODO Auto-generated constructor stub
	}

}

class Business {

	public Business(final String text) {
		// TODO Auto-generated constructor stub
	}

}
class View implements Observer {
	final JTextField field1 = new JTextField();
	final JTextField field2 = new JTextField();
	final Model model;

	public View(final Model model) {
		this.model = model;
		final JPanel panel = new JPanel();
		panel.add(field1);
		panel.add(field2);

		userInput();
		userSubmit();
	}

	private void userSubmit() {
		// user betätigt submit
		// entweder baut die view die model struktur selber wie folgend:
		final Student student = new Student(field1.getText());
		final Business business = new Business(field2.getText());
		model.handle(student, business);

		// oder er übergibt die stringreferenzen an eine model funktion wie
		// folgt:
		model.handle(field1.getText(), field2.getText());

		// auf den ersten blick wirkt die zweite veriante geeigneter für echtes
		// mvc. der nachteil tritt auf, wenn die die anzahl der zu übergebenden
		// referenzen eine entsprechende größer erreichen.

	}

	private void userInput() {
		// user gibt daten ein
		field1.setText("Eignabe1");
		field2.setText("Eignabe2");
	}

	@Override
	public void update(final Event event) {
		event.accept(new Visitor() {
		});
	}
}

interface Observer {
	void update(Event event);
}

interface Event {

	void accept(Visitor visitor);

}

interface Visitor {

}

Ist das sowas in der Art, wie du es dir vorgestellt hast, JavaProfi?
 
Zuletzt bearbeitet:

Rudolf

Bekanntes Mitglied
Hallo GUI-Programmer,

danke für dein Beispiel.

Ohne dich angreifen zu wollen, finde ich dein Beispiel etwas merkwürdig. MVC bedeutet nach meinem Verständnis das hier: Datei:ModelViewControllerDiagram2.svg ? Wikipedia

Bei dir hat man ein Mix. Bei dir erstellt eine Klasse Main die Views und ein Model. Der Controller kennt nur die Model und die View kennt Model und Controller.

Nach meinem Verständnis erstellt aber der Controller die Views und das Model. Er ist der einzige der direkte Referenzen dazu hat und nicht die View. Die Model muss daher ein Observee sein, das über notify die Observer über Veränderungen in der Model-Ebene benachrichtigt.

Aber das bedeutet alles nichts, dass ich recht habe und du unrecht. Kannst du mir bitte erklären warum du der Meinung bist, dass dein Bespiel echtes MVC ist?
 

GUI-Programmer

Top Contributor
Mal vorweg: Dies soll jetzt bitte keine Diskussion über MVC werden

Denn es gibt sehr viele unterschiedliche Interpretationen / Umsetzungen / Möglichkeiten der Implementierung. Eine riesige Diskussion gab es schonmal eben wegen bERt0r Umsetzung von MVC (Kannst ja mal eine Google oder Forumsuche nach "MVC bERt0r" starten!!)

Eine andere Art der Umsetzung, die ich vorwiegend einsetzte: Minimal MVC Example aus meiner Signatur
 

Rudolf

Bekanntes Mitglied
Ich suche aber nach einem optimalen MVC, das meinem Codebeispiel genugtund ist.

Das Problem an beiden MVC Beispielen von dir ist, dass die actionPerform in den Controller ausgelagert ist. Aber was ist, wenn in der Methode von actionPerform viele Referenzen aus der View verarbeitet werden? In deinen Beispielen passiert ja nicht unbedingt viel und man braucht nicht viele Referenzen aus der View, aber was ist wenn doch, z.b. es werden Inhalte aus einem großen Formular herausgelesen.

Was ist dann die beste MVC-Interpretation in diesem Fall? Für alle View-Referenzen public-Getter schreiben? Ist dann irgendwie auch unschön. Oder die Controllerklasse als Parallelclass einsetzen? Also in der gleichen Datei?
 

JavaProfi

Aktives Mitglied
Nach meinem Verständnis erstellt aber der Controller die Views und das Model. Er ist der einzige der direkte Referenzen dazu hat und nicht die View.

Das stimmt so nicht. Der Controller erstellt i.d.R nicht das Model. Das Model existiert unabhängig von irgendeinem Controller und irgendeiner View. Eine Applikation besteht meistens aus mehr als nur einem Fenster. Also aus einer Vielzahl von Views. Jeder View hat in der Regel auch seinen eigenen Controller, aber nicht sein eigenes Model.

Soweit die Theorie, aber wie GUI-Programmer schon gesagt hat, gibt es Abwandlungen des MVC wie MVA (Model View Adapter) oder MVP. Das klassische MVC besitzt nur ein Model, mehrere Views und mehrere Controller, wobei i.d.R. zwischen einem Controller und einem View eine 1:1 Beziehung existiert.

Daher existiert in vielen Applikationen für jede View eine eigenes Package in dem sich auch der zugehörige Controller befindet. (Eine View kann allerdings wieder aus mehreren Teilsichten bestehen, die wiederum eigene Controller haben können.)

Da der Controller ja auch die Komponenten des View auslesen muss, sind diese dann protected deklariert. Damit kann nur der Controller des View auf die Komponenten zugreifen.

Die Bekanntgabe von Änderungen an relevanten Daten im Modell geschieht nach dem Entwurfsmuster „Beobachter“. Das Modell ist das zu beobachtende Subjekt, auch Publisher, also „Veröffentlicher“, genannt. Das Model implementiert also das Interface "Observable". Die View beobachtet das Model, implementiert somit das "Observer"-Interface.

Je nach Implementierung des MVC (und das sind alles konforme Implementierungen) kann auch der Controller das Modell beobachten, um auf Änderungen des Models reagieren zu können.

Gruß
JP
 
Zuletzt bearbeitet:

GUI-Programmer

Top Contributor
Wollt eigentlich nur sagen, dass es oft vorkommt, dass der/ein Controller speziell der View angepasst wird, bzw. zu einer best. View gehört. Sonst hat JavaProfi schon alles gesagt.
 

Rudolf

Bekanntes Mitglied
Oh, ok danke dann für diese Informationen.

Jetzt die Frage. JavaProfi hat gesagt, dass die Felder der View oft protected deklariert sind, damit sie der Controller auslesen kann. Das macht so für mich keinen Sinn, weil nur Klassen, die eine andere Klasse mit protected Feldern erweitern, darauf zugreifen können. Erweitert der Controller die View Klassen oder wie ist das gemeint?
 

GUI-Programmer

Top Contributor
Erweitert der Controller die View Klassen oder wie ist das gemeint?

Nein, ist nicht so gemeint. Protected deshalb, damit man eben nicht für jede GUI-Komponente ala JPanel Instanz, JLabel Instanz... extra Getter schreiben muss (Setter werden in der Regel nicht benötigt). Und die Grundregel lautet ja: So wenig Sichtbarkeit wie nur möglich. Folglich würde sich Package-Private auch anbieten.

Dennoch kreiere ich persönlich dann doch lieber Getter, bzw. lasse sie mir von Eclipse kreieren.
 

JavaProfi

Aktives Mitglied
Jetzt die Frage. JavaProfi hat gesagt, dass die Felder der View oft protected deklariert sind, damit sie der Controller auslesen kann. Das macht so für mich keinen Sinn, weil nur Klassen, die eine andere Klasse mit protected Feldern erweitern, darauf zugreifen können.

Das ist nur die halbe Wahrheit.:)
Das was ich gepostet habe macht schon Sinn. Sonst würden einige meiner MVC-designed Applications nicht laufen.:D

Zum Nachlesen: Have a look here --> Java ist auch eine Insel – 6.7 Vererbung und dort unter 6.7.5
oder auch hier: Controlling Access to Members of a Class (The Java™ Tutorials > Learning the Java Language > Classes and Objects)

Wenn du magst, kannst du natürlich auch über getter-Methoden auf deine dann private deklarierten Komponenten zugreifen.


@GUI-Programmer
...Und die Grundregel lautet ja: So wenig Sichtbarkeit wie nur möglich. Folglich würde sich Package-Private auch anbieten.
Geht natürlich auch, dann kann aber eine SUB-Class nicht mehr auf die Member-Variable zugreifen.

Gruß
JP
 
Zuletzt bearbeitet:

Rudolf

Bekanntes Mitglied
Nein, ist nicht so gemeint. Protected deshalb, damit man eben nicht für jede GUI-Komponente ala JPanel Instanz, JLabel Instanz... extra Getter schreiben muss (Setter werden in der Regel nicht benötigt). Und die Grundregel lautet ja: So wenig Sichtbarkeit wie nur möglich. Folglich würde sich Package-Private auch anbieten.

Dennoch kreiere ich persönlich dann doch lieber Getter, bzw. lasse sie mir von Eclipse kreieren.

Eine andere Programmierregel lautet, dass man sich niemals auf die Ordnerstruktur bezüglich visibility der Felder verlassen soll.

Ein Beispiel.

Ich nehme package private und haue für jede View ein eigenes Package raus, in dem die View und der dazugehörige Controller befinden. Die Felder der View mache ich als package private. Dann kommen mehrer Viewordner nach dem gleichen Schema dazu.

Später kommt ein **** und denkt sich, dass es cooler wäre, wenn alle Viewklassen in einen Ordner kommen und alle Controllerklasse in einen anderen Ordner. Dann habe ich ein Problem mit der Visibility.

Was sollte man tun?

Kann jemand offizielle Codingregeln zitieren, die das Problem aufgreifen und eine Empfehlung geben?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Semox Warum baut man eine GUI nicht in der main-Methode? AWT, Swing, JavaFX & SWT 16
B Fensterinhalt baut sich erst bei Größenveränderung auf AWT, Swing, JavaFX & SWT 3
L Wie baut man ein SWT-Programm auf? AWT, Swing, JavaFX & SWT 4
S JavaFX Fehler zwischen View und Controller bei MouseEvent (MVC) AWT, Swing, JavaFX & SWT 13
J Java FX NullPointerException, ObservableList wird in View nicht angezeigt.. AWT, Swing, JavaFX & SWT 34
J Saubere Trennung Model, View, Controller Javafx AWT, Swing, JavaFX & SWT 10
H 3 verschiedene Nachrichten in einer FXML View die Infos kommen aus DB AWT, Swing, JavaFX & SWT 4
ralfb1105 JavaFX Exception Message von Model Class via Controller in View darstellen AWT, Swing, JavaFX & SWT 39
S JavaFX Boolean ändern Table View AWT, Swing, JavaFX & SWT 14
M Swing MVC-Pattern - View mit mehreren Models AWT, Swing, JavaFX & SWT 5
M JavaFX - Array in View auslesen AWT, Swing, JavaFX & SWT 12
4a61766120617274697374 dynamische Tree View AWT, Swing, JavaFX & SWT 2
H JavaFX Ein View vorschalten Exception AWT, Swing, JavaFX & SWT 7
M SWT View nicht mehr sichtbar AWT, Swing, JavaFX & SWT 2
G JavaFX "Framework" zur View Ersellung AWT, Swing, JavaFX & SWT 0
M JavaFX Image View Würfel berechnen AWT, Swing, JavaFX & SWT 3
K Panels mit eigenen Controllern in Main-View einbauen AWT, Swing, JavaFX & SWT 4
T View AccessibleContext AWT, Swing, JavaFX & SWT 0
S Swing Auf Änderungen eines Models in der View einer JTable reagieren AWT, Swing, JavaFX & SWT 1
S Swing JPanel in View ersetzen AWT, Swing, JavaFX & SWT 10
O Swing JTextField Sync View -> Model AWT, Swing, JavaFX & SWT 3
S View-Komponenten im Controller bekannt machen AWT, Swing, JavaFX & SWT 7
L View aus dem MVC ist immer die GUI? AWT, Swing, JavaFX & SWT 5
Nicklas2751 Table View zeigt keinen Inhalt nur leere Zeilen AWT, Swing, JavaFX & SWT 2
G Swing MVC / View - Controller AWT, Swing, JavaFX & SWT 7
N MVC - Logik zum Verändern der View AWT, Swing, JavaFX & SWT 8
V Eclipse View Right-Click Menu hinzufügen AWT, Swing, JavaFX & SWT 2
D Drag-Action: Innerhalb meiner View? AWT, Swing, JavaFX & SWT 3
C SWT-Elemente an View-Fenster angleichen und automatisch resizen AWT, Swing, JavaFX & SWT 3
G Swing Höhe des View eines JScrollPane fest auf Höhe des JScrollPane setzen! AWT, Swing, JavaFX & SWT 4
R Model View Controller Konzept AWT, Swing, JavaFX & SWT 2
R Swing Designfrage - Zusammenspiel Model / View AWT, Swing, JavaFX & SWT 10
J Swing SwingActions und das Problem auf den View bzw. das Model zuzugreifen AWT, Swing, JavaFX & SWT 2
D Swing JTable Model View Problem AWT, Swing, JavaFX & SWT 6
H shell in view implementieren; menu mit keystroke unterlegen AWT, Swing, JavaFX & SWT 8
M Swing Model an View binden AWT, Swing, JavaFX & SWT 4
M Swing Von einem Controller aus View-Elemente ändern AWT, Swing, JavaFX & SWT 11
H Swing JScrollPane mit JPanel als View AWT, Swing, JavaFX & SWT 3
B Sudokuartiger View (RadiobuttonTableView) mit JFace Viewer? AWT, Swing, JavaFX & SWT 3
N FileChooser in View AWT, Swing, JavaFX & SWT 3
F Swing J(X)Table Spalten umsortieren NUR im View (Wie finde ich eine Spalte nach Name?) AWT, Swing, JavaFX & SWT 3
hdi Swing JTable & Filtern: Daten nicht in der View AWT, Swing, JavaFX & SWT 2
B SWT Textdatei Lesen und Anzeige in View - Zeichensatzproblem AWT, Swing, JavaFX & SWT 4
D Design - View & Controller AWT, Swing, JavaFX & SWT 2
H Eclipse View / Window Layout AWT, Swing, JavaFX & SWT 3
N RCP/SWT View durch Programm auf 2. Bildschirm verschieben AWT, Swing, JavaFX & SWT 2
B view in andere View einbinden AWT, Swing, JavaFX & SWT 5
G RCP - SWT :: Scrollbars in einer View AWT, Swing, JavaFX & SWT 10
Zed JTable view auf Selection setzen AWT, Swing, JavaFX & SWT 2
R MVC: System.out.prinln in View umleiten geht nicht richtig AWT, Swing, JavaFX & SWT 7
K JSpinner - Model <-> View, unterschiedliche Werte AWT, Swing, JavaFX & SWT 9
E Mehrere Views in einer View AWT, Swing, JavaFX & SWT 3
TRunKX Ereignissweitergabe von Jlist.getSelected() aus der View AWT, Swing, JavaFX & SWT 7
P Verbindung View und Controller AWT, Swing, JavaFX & SWT 3
D Scrollbalken in einem View AWT, Swing, JavaFX & SWT 2
I Shell aus einer Plugin-View öffnen . AWT, Swing, JavaFX & SWT 4
B View zeichnet Daten aus dem Model ohne Update AWT, Swing, JavaFX & SWT 4
F MVC: Update von View und Controller AWT, Swing, JavaFX & SWT 5
S MVC - Neues Frame, neue View, neuer Controller? AWT, Swing, JavaFX & SWT 3
C Model View Controller - Beispielimplementation AWT, Swing, JavaFX & SWT 5
M SWT und Model View Controller? AWT, Swing, JavaFX & SWT 8
M auch JScrollPane aber mit Zoomen, wie wird der View gesetzt AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen


Oben