Modell View Controller Verständnisfrage

sharkattack

Mitglied
Hallo zusammen

Nachdem ich im Winter schon mal ein kleines Java Programm geschrieben habe, welches Rechnungen mit Preislisten vergleicht, hat mich vor ein paar Wochen wieder das Java Fieber gepackt. Da mein erstes Programm zwar funktioniert, aber der Code das reinste Chaos ist, habe ich mich entschlossen, mich etwas ins MVC Muster einzulesen. Des Weiteren wollte ich gerne JavaFX benutzen und habe deshalb folgendes Tutorial gemacht: http://code.makery.ch/library/javafx-8-tutorial/part1/

Das Tutorial ist eigentlich gut gemacht, allerdings verstehe ich ein paar Sachen nicht so ganz. Zum Beispiel werden die Methoden zum Laden und Speichern von Daten in die MainApp geschrieben. Auch die Arrayliste mit den Kontaktdaten befindet sich in der MainApp. Ist das nur so gemacht, weil die Anwendung ziemlich klein ist? Wo legt ihr normalerweise die Methoden zum Speichern und Laden der Daten fest? In einem Modell mit dem Namen InputOutput oder IO, oder auch direkt in der MainApp? Befinden sich Arraylisten normalerweise auch immer in der MainApp und ein Controller fügt dann die Daten mit z.B. (mainApp.getPersonData().add(tempPerson);) hinzu? Oder befinden sich diese wieder in einem seperaten Modell, das die Methode getPersonData besitzt?

Die MainApp ist ja eingentlich ein Controller, oder? Ich dachte immer alles was mit Daten zu tun hat, gehört in ein Modell.

Ich hoffe ihr versteht meine Fragen. :) Bin leider noch Anfänger und würde mich sehr freuen, wenn mir jemand etwas Licht ins Dunkel bringen könnte.

Besten Dank schon mal.
LG
 

JStein52

Top Contributor
Als Faustregel gilt schon mal dass das Model unabhängig von View und Controller ist. D.h. du solltest die Oberfläche von JavaFX nach SWING umbauen können ohne am Model was zu verändern.
 

sharkattack

Mitglied
Besten Dank JStein52. Und wie machst du das normalerweise? Stehen bei dir Methoden zum Laden und Speichern direkt in der MainApp, oder machst du dafür ein extra Modell? Und befinden sich zum Beispiel Arraylisten in denen zum Beispiel Kontaktdaten hinzugefügt werden auch in der MainApp oder würdest du diese in ein seperates Modell, zum Beispiel mit dem Namen Kontaktliste speichern?
Wie du sagst, gilt als Fausregel, dass man die Oberfläche von JavaFX nach SWING umbauen können sollte. Dadurch könnte man aber dann im Prinzip die meisten Methoden in die MainApp packen. Aber meine Bedenken sind, dass diese dann mit der Zeit sehr unübersichtlich wird, je grösser die Anwendung wird. Deshalb interessiert es mich auch, wie ihr das normalerweise macht. :)
 

JStein52

Top Contributor

sharkattack

Mitglied
OK, ich denke ich werde für die angesprochenen Sachen auch eigene Klassen erstellen. Besten Dank. Vielleicht kann ich ja dann mal jemandem meinen Code zusenden, wenn er mal einigermassen funktionstüchtig ist und er sagt mir dann, was schlecht und was recht ist. :)
 

AndyJ

Bekanntes Mitglied
Wie JStein52 schon gesagt hat, sollte es moeglich sein den View jederzeit auszutauschen. Dummerweise ist das leichter gesagt als getan, denn meistens werden Model, View und Controller im selben Projekt erstellt. Das fuehrt dazu, dass sich Code an den Boundaries vermischt und die Trennung nicht mehr sauber ist. Zum Beispiel wandert Controllercode leicht mal in den View-code, wenn der Programmierer Anwendungslogik in einem Listener implementiert (ActionListener, FocusListener, etc.). Wir hatten das Problem vor einiger Zeit an meinem Arbeitsplatz: eine JavaFX Anwednung sollte nach Swing portiert werden. Das war besonders aufwendig, denn JavaFX ist nicht nur ein UI-Toolkit, sondern auch ein Databinding Framework. Das ganze Model war in JavaFX-Properties implementiert...
Wir haben dann Model, View und Controller komplett getrennt und in verschiedenen Projektdirectories organisiert:
MVCdetails.png

Das Model ist read-only aus der Sicht des View:
model.png
Und so wird der View aktualisiert:
executionsequence.png
Ist ein ganz schoener Aufwand, aber am Ende zahlt es sich aus.

Cheers,
Andy
 

JStein52

Top Contributor
Beispiel für gut umgesetztes MVC
Ja. Der Controller sollte die Schnittstelle zwischen den Benutzerein/ausgaben und dem Model darstellen, bei Swing-Applikationen also typischerweise die EventHandling-Methoden. Die Business-Logik sollte dann im Model sein.
Wenn die Business-Logik z.B. darin besteht die Wurzel einer Zahl auszurechnen dann sollte der Controller diese Zahl entgegennehmen und dem Model zur Berechnung übergeben. Die Berechnung sollte nicht im Controller stattfinden.
 

AndyJ

Bekanntes Mitglied
Der Controller enthaelt die Businesslogik und das Model haelt die Daten. Wenn ihr es anders macht, aendert das nichts am Design, das es erlauben sollte den View jederzeit zu ersetzen. Die Listener und Eventhandling-Methoden, die die Benutzereingaben verarbeiten sind nicht Teil des Controllers in dem von mir vorgeschlagenen Design. Es ist genau diese Unklarheit, die oft Probleme verursacht.

Cheers,
Andy
 

mrBrown

Super-Moderator
Mitarbeiter
Der Controller enthaelt die Businesslogik und das Model haelt die Daten. Wenn ihr es anders macht, aendert das nichts am Design, das es erlauben sollte den View jederzeit zu ersetzen. Die Listener und Eventhandling-Methoden, die die Benutzereingaben verarbeiten sind nicht Teil des Controllers in dem von mir vorgeschlagenen Design. Es ist genau diese Unklarheit, die oft Probleme verursacht.
Ja genau - es ist eben diese Unklarheit, die oft Probleme verursacht (ich rede btw von dem MVC, was zB Fowler, Martin, Beck etc vertreten).

Die Controller in deinem Beispiel enthalten die Businesslogik und eben nicht das Eventhandling - und sind genau deshalb eben keine Controller im Sinne von MVC, sondern Teil des Models.
Deine View dagegen (laut dir View + Eventhandling) ist sowohl View als auch Controller - und nicht die reine View.


Wenn ihr es anders macht, aendert das nichts am Design, das es erlauben sollte den View jederzeit zu ersetzen.
Es geht nicht um das reine ersetzte der View bei gleichzeitigem behalten des Controllers - MVC erlaubt das austauschen von zwei Dingen:
- dem Controller, bei beibehalten von View und Model, welches einfach nur zu anderem verhalten führt (zB Daten editieren vs Daten nur lesen als User)
- der gesamten Präsentationsschicht, die sowohl Controller als auch View beinhaltet.

Das einzig konstante ist das Model - und das muss völlig unabhängig von Controller und View funktionieren - ansonsten hat man genau das Problem, was du in deinem Ursprungspost beschrieben hast: das ganze vermischt sich an den Grenzen und es wird ein riesiger unwartbarer Haufen.
 

sharkattack

Mitglied
Es ist wirklich interessant hier mitzulesen, danke dafür. Es scheint irgendwie nicht so ganz klar zu sein, wo die Businesslogik hingehört. Einige sagen in den Controller, andere ins Model. Bei all den Seiten, die ich mir bis jetzt durchgelesen habe, ist die Mehrheit aber der Meinung, dass sie ins Model gehört.
Ich versuche im Moment gerade einen Profilmanager zu erstellen. Also wenn ich das richtig verstanden habe müssen Methoden um zum Beispiel ein Profil zu löschen oder hinzufügen in das Model, oder?
Ich habe zwei Klassen für das Profil. Eines heisst Profil und dort sind die Felder Profilname, Profilpfad und Adressbuch enthalten, sowie die getter und setter Methoden für die jeweiligen Felder. Dann habe ich noch eine zweite Klasse mit dem Namen Profilliste, mit dieser kann die ArrayListe für die Profile in eine Datei gespeichert oder auch geladen werden.
Nun frage ich micht, wo ich die Methoden addProfile, removeProfile oder renameProfile erstellen sollte. Direkt in der Klasse Profil, in der Klasse Profilliste, oder sollte ich dafür wieder eine neue Klasse erstellen?
 

mrBrown

Super-Moderator
Mitarbeiter
Die gehört nach dem was du sagst in die Klasse ProfilListe - diese stellt dann eine Liste der aktuellen vorhandenen Profilen dar, und bietet Möglichkeiten, diese zu verändern.
Der Controller ruft dann bei Klick auf den entsprechenden Button die jeweilige Methode im Model auf.

Das Laden und Speichen von Profilen würd ich dafür aber in eine andere Klasse auslagern.
 

MarzAttak

Mitglied
Natürlich kann man in einem MVC-Pattern den View mit JavaFX gestalten. Allerdings ist JavaFX (ebenso wie C#/Xaml) aufgrund seines Binding-Konzeptes - so wie ich es verstanden habe - eher für ein MVVM-Pattern konzipiert. Der Controller ist dann nicht mehr nur der "blinde" Schalterschrank, in dem View und Model verkabelt werden, sondern stellt die Daten des Models derart bereit, dass der View seine Darstellung daran binden kann.
Falls es dich nicht zu sehr verwirrt, schau dir doch mal den Wikipedia-Artikel zum Model-View-Viewmodel-Konzept an.
 

AndyJ

Bekanntes Mitglied
Man kann ewig darueber streiten, wo man die Businesslogik abbildet. Aber wie auch immer man sich entscheidet, wichtig ist eine saubere Trennung. Sobald Teile deiner Programmlogik z.B. in einem java.awt.event.ActionListener (AWT/Swing controller) oder dein Model in einem javafx.beans.property.Property<T> enden, bist du geliefert weil die Trennung perdu ist. In meinem Modell habe ich vielleicht einfach nur einen ungeschickten Namen verwendet. Ich sehe den Controller als die Komponente, die die Businesslogik enthaelt. Swing-entwickler sehen den Controller als das Element, dass UI events verarbeitet und den View auch updated. Swing ist ja auch kein 100% MVC, es folgt dem Model-Delegate Pattern (https://www.safaribooksonline.com/library/view/java-swing/156592455X/ch01s04.html). Aber ich denke es wird klar worauf ich hinaus will. Was mein Entwurf vor allem macht ist, dass er auch unerfahrenen Entwicklern im Team hilft es richtig zu machen bedingt durch die "physikalische" Trennung. Man kann ein anderes Design verwenden und die gleiche, strikte Trennung herbeifuehren, dann hat man den gleichen, positiven Effekt.
 

sharkattack

Mitglied
Ich habe jetzt den Quelltext vom Tutorial ziemlich umgeschrieben, so dass die Controller eigentlich nur noch die Daten entgegennehmen und diese entsprechend weiterleiten. Für die Überprüfung der eingegebenen Daten habe ich eine neue Klasse ValidityUtil erstellt, welche die Textfelder für Namen, E-Mail, usw. überprüft. Somit ist mein Controller jetzt eigentlich nur noch der genannte "blinde" Schalterschrank, der die Daten nur entgegennimmt und entsprechend weiterleitet. So dürfte es eigentlich sehr einfach sein, die Oberfläche nach Swing, usw. umzubauen. Für die JavaFX Oberflächen verwende ich fxml.
In den letzten Wochen habe ich stundenlang überlegt, Code umgeschrieben, wieder getestet und wieder umgeschrieben. :( Immer war ich mit etwas nicht zufrieden. Nun bin ich doch froh, dass es sich doch noch gelohnt hat und ich endlich einen etwas besseren Durchblich, auch dank dem Forum hier habe.:) Nochmals danke dafür.
 

AndyJ

Bekanntes Mitglied
Momentan portiere ich eine Swing Anwendung nach SWT. Dieses Programm hat einen Persistence Layer, der eine Klasse Ship zurueckliefert, die folgende Methode enthaelt:

Code:
public BufferedImage getPhoto() {
    ...
}

Ein schoenes Beispiel, das zeigt wie leicht sich View-code ins Model mogeln kann. Ich kenne den Entwickler nicht persoenlich, aber unerfahren war der auf keinen Fall.
 

Meniskusschaden

Top Contributor
Hm, wahrscheinlich habe ich da noch ein Verständnisproblem. Warum ist das denn View-Code? Ein Photo kann doch genauso ein Datenelement des Schiffes sein, wie jede andere Information auch. Ich hätte hier weniger den Verdacht, dass View und Model vermischt werden, sondern eher, dass gegen das Prinzip "Programmiere gegen Schnittstellen statt Implementierungen" verstossen wird. Geht es dir darum, dass das Model hier überhaupt dafür zuständig ist, ein Photo zu liefern oder darum, dass dafür BufferedImage benutzt wird?
 

AndyJ

Bekanntes Mitglied
java.awt.image.BufferedImage benutzt man fuer awt und Swing, waehrend man fuer ein SWT Image die bytes oder einen Inputstream darauf benoetigt. Damit ist das Model an Swing gebunden.
 

andy82

Mitglied
Als Faustregel gilt schon mal dass das Model unabhängig von View und Controller ist. D.h. du solltest die Oberfläche von JavaFX nach SWING umbauen können ohne am Model was zu verändern.
Ich würde hier die Persistence-Daten(-Model) nennen - die mehr Nähe zu Business-Daten sind, denn Model in Swing sind nicht gleich wie "Model" in FX, also nicht austauschbar. Zu jedem Komponente in Swing entspricht einem Modeltyp (JTextfield ~ Document, JList ~ DefaultListModel, JTable ~ TableModel, ...). Konzept der Model in JavaFX (DataBilding und Verwendung von HüllenKlasse wie Observable+++ ) finde ich viel besser als Swing. Ich finde damals Sun-Programmierer sehr schlecht DefaultListModel eingebaut hatte, damit Java den Ruf hat, langsam zu sein - (Ich selbe benutzte niemals DefaultListModel, sondern eine andere, damit diese Bremse umgehen zu können). Also für Java-Newcomer würde ich dringend zu FX empfehlen. Den Aufwand Swing zu lernen, soll man gleich zu FX wechseln.

Ich habe jetzt den Quelltext vom Tutorial ziemlich umgeschrieben, so dass die Controller eigentlich nur noch die Daten entgegennehmen und diese entsprechend weiterleiten. Für die Überprüfung der eingegebenen Daten habe ich eine neue Klasse ValidityUtil erstellt, welche die Textfelder für Namen, E-Mail, usw. überprüft. Somit ist mein Controller jetzt eigentlich nur noch der genannte "blinde" Schalterschrank, der die Daten nur entgegennimmt und entsprechend weiterleitet. So dürfte es eigentlich sehr einfach sein, die Oberfläche nach Swing, usw. umzubauen. Für die JavaFX Oberflächen verwende ich fxml.
In den letzten Wochen habe ich stundenlang überlegt, Code umgeschrieben, wieder getestet und wieder umgeschrieben. :( Immer war ich mit etwas nicht zufrieden. Nun bin ich doch froh, dass es sich doch noch gelohnt hat und ich endlich einen etwas besseren Durchblich, auch dank dem Forum hier habe.:) Nochmals danke dafür.
Bei einer Projekt bleibt nicht stur MVC, sondern mehr in der Richtung mehrere Schichten. In Gui-Schicht könnte MVC oder MVVM ...sein, wichtig dass die Steuerungen der Gui-Model und Gui-Control (ActionEvent ...) getrennt mit der Steuerung der BusinessDaten (DataChangeEvent ...) sind. Die letztere sind mehr in Richtung PersistenceManager(Schicht), die wiederum mit dem Schicht Wrapper, wo wieder in mehreren Unterschichten geteilt sind (SQL, NonSQL, XML, File, Cloud, ...), wo Du In/Output nennt.
 
Zuletzt bearbeitet:

mrBrown

Super-Moderator
Mitarbeiter
Ich würde hier die Persistence-Daten(-Model) nennen - die mehr Nähe zu Business-Daten sind, denn Model in Swing sind nicht gleich wie "Model" in FX, also nicht austauschbar. Zu jedem Komponente in Swing entspricht einem Modeltyp (JTextfield ~ Document, JList ~ DefaultListModel, JTable ~ TableModel, ...). Konzept der Model in JavaFX (DataBilding und Verwendung von HüllenKlasse wie Observable+++ ) finde ich viel besser als Swing.
Das was bei MVC das Model ist, ist sowohl bei Swing als auch JavaFx im Idealfall völlig unabhängig von beiden - deren Model fällt eher unter Das ViewModel in MVVM.

Ich finde damals Sun-Programmierer sehr schlecht DefaultListModel eingebaut, damit Java den Ruf hat, langsam zu sein - (Ich selbe benutzt niemals DefaultListModel, sondern eine andere, damit diese Bremse umgehen zu können.
Den Ruf langsam zu sein hat es eher, weil Java früher ohne JIT allgemein recht langsam war^^
 

andy82

Mitglied
...
Den Ruf langsam zu sein hat es eher, weil Java früher ohne JIT allgemein recht langsam war^^
Meine Behauptung bleibt:
Auch ohne JIT ist Java auch schnell genug, wenn Sun-Programmierer nicht den schweren Fehler (bis jetzt nicht aufgeräumt!) bei fast allen abgeleiteteten Klassen von AbstractListModel (wie DefaultComboBoxModel, DefaultListModel ...) nicht eingebaut hätte. Um Item zur List hinzufügen, bitten sie nur 1 Methode addElement(E aItem) oder bei DefaultListModel noch eine weitere Methode add(int index, E element). Intern addiert eine private Vector delegate dieses Item, werfe einen Event auf. Siehe z.B. die Original-Code:
Code:
     private Vector<E> delegate = new Vector<E>();
...
   public void add(int index, E element) {
        delegate.insertElementAt(element, index);
        fireIntervalAdded(this, index, index);
    }
...
    public void addElement(E element) {
        int index = delegate.size();
        delegate.addElement(element);
        fireIntervalAdded(this, index, index);
    }
Wenn man die Methode fireIntervalAdded(...) weiter verfolgt, kommt irgend einmal zu JList. bzw. JComboBox.repaint(). Genau hier kennt jeder sofort, was passiert, wenn man Hundert, Tausends oder Millionen Items zur ListModel => Gui wird Hundert, Tausend oder Millionen mal neugezeichnet. In der von Sun angebotenen ListModel gibt es keine Möglichkeiten eine Collection zu delegate auf einmal zu addieren, erst dann soll Gui neugezeichnet werden. Jeder Versuch, diese o.g. Methoden zu überschreiben bringt keinen Erfolg, weil ListContent delegate privat definiert ist.
Meine Rettungsweg war:
- ich kopiere Original-Code und baut davon selbst in meinem eigenem framwork, füge die Methode add(index, Collection) hinzu. Sagen wir mal, generiere eine Vector von tausend Item, addiere zu beiden ListModel, bei meiner entworfenen List dauert ms, bei Sun kann man erst zum Kaffee-Kochen bis die Liste gefüllt sind. Es war vor ca. 15 Jahren, als ich diesen Test gemacht hatte. Genaue Zeitmessung habe ich nicht mehr im Kopf, und Beispiel für die Messung behalte ich ach nicht mehr. Jede kann die ganz schnell probieren.
- Bei TableModel passiert so was nicht. Stelle man vor, wie oft JList und JComboBox benutzt wird, wenn die Anzahl der Items nicht sehr groß ist, merkt man nicht. Aber!
- Bei JavaFX sind die Models selbst Collection umgehüllt von Observeable-Klassen, also kann man Items direkt zu den Kernen addieren (ohne Event aufzuwerfen) oder wenn gewollt Items zu Observeable, um Event aufzuwerfen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
E Compiler-Fehler nullPointerException in verschachteltem Modell Java Basics - Anfänger-Themen 6
K Hamstersimulator / Hamster Modell Lösungen gesucht Java Basics - Anfänger-Themen 3
W OOP Action Listening und MVC-Modell Java Basics - Anfänger-Themen 3
A größeres MVC-Modell Java Basics - Anfänger-Themen 12
I Kamera anschließen / Bild machen / Live View / Externe Blitz Java Basics - Anfänger-Themen 19
sserio Java Fx, wie erstellt man einen EventHandler, der durch das Drücken eines Button Texte in eine Table view einfügt Java Basics - Anfänger-Themen 17
G Model View Controller Java Basics - Anfänger-Themen 7
G SQL View query Java Basics - Anfänger-Themen 4
H Best Practice View probleme Java Basics - Anfänger-Themen 2
L Java Package View Java Basics - Anfänger-Themen 6
S Model View Controller: Verständnisproblem Java Basics - Anfänger-Themen 13
M Erste Schritte Eclipse + design view Java Basics - Anfänger-Themen 3
I Klassen Java Qt Model/View Datenhaltung Java Basics - Anfänger-Themen 4
R aktualisierung des View im MVC-Pattern Java Basics - Anfänger-Themen 5
G Eclipse: In Problems View schreiben? Java Basics - Anfänger-Themen 10
A Datentypen Typecast im View Java Basics - Anfänger-Themen 4
A OOP MVC Frage View Java Basics - Anfänger-Themen 2
F View überwachen Java Basics - Anfänger-Themen 6
C OOP Model View Controller - Prinzip Java Basics - Anfänger-Themen 6
S JTree, Problem mit View Update Java Basics - Anfänger-Themen 2
K JAVA HEX View! Java Basics - Anfänger-Themen 2
K Model-View-Controller Java Basics - Anfänger-Themen 15
K Frage zum Model View Controller Prinzip Java Basics - Anfänger-Themen 6
M Controller + View: Fehlermeldungen Java Basics - Anfänger-Themen 2
G Einbindung von MVC (Model-View-Controll) Java Basics - Anfänger-Themen 8
megachucky Model View Controller Pattern - Suche Hilfe bei Anwendung Java Basics - Anfänger-Themen 4
E MVC - Was darf View Java Basics - Anfänger-Themen 15
E MVC - ein View für mehrere Models Java Basics - Anfänger-Themen 2
S Model-View-Controller Konzept Beispiel Java Basics - Anfänger-Themen 11
EchtKeineAhnungManchmal Controller aus FXML Datei entfernen Java Basics - Anfänger-Themen 49
B Objekt von EJB in Controller (CDI) - Klasse füllen? Java Basics - Anfänger-Themen 3
H Eine befühlte Klasse weiter geben an Controller Java Basics - Anfänger-Themen 12
R Variablen Variable an FXML-Controller übergeben Java Basics - Anfänger-Themen 4
N JavaFX - (Controller) - Klasse verkleinern Java Basics - Anfänger-Themen 8
J MVC Pattern, mehrere Controller/Views/Models Java Basics - Anfänger-Themen 0
Q MVC Verständnisproblem: Controller vs model.modelChanged() Java Basics - Anfänger-Themen 0
F MVC -> Probleme beim Controller Java Basics - Anfänger-Themen 6
F Viele Controller-Klassen Java Basics - Anfänger-Themen 5
Antoras Singleton oder Controller / Datenverwaltungsklasse? Java Basics - Anfänger-Themen 10
T Kommunikation zwischen Controller und GUI Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben