# MVC Konzept



## Guest (3. Jul 2007)

Hallo,

wieder mal eine Designfrage,

Also ich schreibe gerade eine datenbankprog bei dem der zugriff über mi läuft. Der Client erhält , die einzelnen daten als spezifische datenobjekte die in einer schnitttstelle gespeichert sind.
Da ich das mvc konzept umsetzen will, habe ich mir mehrere Packages angelegt, also eins für das model eins für den controller und eins für die view. Wenn ich in der view jetzt den button zum aktualisieren drücke, ruft der controller für das modell die methode refresh auf, welche eine methode im rmi client aufruft, um die aktuellen daten zu erhalten. Anschließend werden die daten in einer klasse ModelData gespeichert und die listener darüber informiert, das sich etwas geändert hat. Daraufhin aktualisiert sich die view und zeigt die neuen daten an. Soweit zur Theorie. Nun zur Praxis

Ich weiß nämlich nicht was besser ist, eine Klasse für jede Datenklasse(z.b Nutzer, Adressen u.s.w ) mit einer get-, set- Methode, einem addListener, removelistener, statusChanged methode, oder alle in eine.

Habe auch schon überlegt das ganze mit Verebung zu lösung als eine Hauptklasse und die ganzen datenklassen als unterklassen. Ist das bei diesem Konzept möglich, weil sie ja eigentlich alle dasselbe enthalten, oder bietet sich da irgendein entwurfsmuster an wie factory oder ähnliches was ich mir mal anschauen sollte.

Und eine zweite Frage, wie mache ich die fehlerbehandlung bei meinem konzept, also hauptsächlich die, wenn es beim model zu fehlern kam, falscheingeb oder verbindung weg oder ähnliches


----------



## Gast (3. Jul 2007)

Hallo,

schade noch keine antwort da woran liegts denn frage nicht richtig erläutert? 
Ihr könnt mir auch gerne nur einen teil beantworten vielleicht komm ich ja dann slebr auf dentrest.

wäre euch für eure hilfe wirklich dankbar


----------



## ARadauer (5. Jul 2007)

Gast hat gesagt.:
			
		

> Ich weiß nämlich nicht was besser ist, eine Klasse für jede Datenklasse(z.b Nutzer, Adressen u.s.w ) mit einer get-, set- Methode, einem addListener, removelistener, statusChanged methode, oder alle in eine.


also du meinst mehrere models, oder nur eines? Also kommt drauf an, wenn du zum beispiel eine tabelle (jtable) für nutzer und eine tabelle für adressen hast, würd ich sogar eigene views und controller machen. wies halt in der anwendung logisch zusammen gehört. wenn du jedoch ein formular hast, in dem ein benutzer mit seiner adresse angezeigt wird, würde ich es in ein model nehmen.



und zum thema fehlerbehandlung: ich würd eine exception an den controller weiterreichen. also user drückt buttn, controller will refresh des models aufrufen, fehler > model wirft exception an controller. mein hintergedanke dabei: stell dir vor, du hast mehrere views, die an änderungen im model interessiert sind, jetzt kommt von view A eine anweisung und im model passiert ein fehler. will view B das jetzt wissen oder nicht, ich finde nicht. drum soll der controller entscheiden, was passieren soll....



is das nur meine meinung, wenn jemand eine andere ansicht zum thema hat, können wir gerne darüber diskutieren.
ich finde dass, das einsetzen von design patterns eine übungssache ist. ich kenn das mvc jetzt seit einem jahr. hatte am anfang immer probleme damit, ich hab es jetzt mehrmals eingesetzt und arbeite damit jetzt ganz anders wie am anfang... und jetzt liebe ich es


----------



## Philip (7. Jul 2007)

Hi,

also kann auch sein, dass ich mich täusche. Würde mich freuen, wenn wir darüber diskutieren können. Ich bin auch noch am dazulernen.  
MVC ist für mich eher ein Paradigma als ein echtes Entwurfsmuster. Und ich verstehe es so, dass jede Komponente eine Model, ein Controller und eine (oder mehrere) Views haben sollte und diese getrennt voneinander ausgetauscht werden können. Wobei das Model sich auch wieder aus verschiedenen Datenobjekten zusammen setzen kann und auch von anderen Komponenten ggf. verwendet wird usw. Die Zuordnung ist also auch nicht unbedingt eindeutig.
Man beachte den allgemeinen Begriff "Komponente". Das kann alles mögliche sein, was auf der Oberfläche dargestellt werden soll. Also auch ein Button oder ein Label ist nichts anderes als eine Komponente, allerdings mit trivialem Model und ein Label hat auch keinen Controller. Oder auch ein ganzes Formular kann man im Sinne von MVC als Komponente betrachten.

Und die drei Komponenten (Model, View, Controller) arbeiten wirklich eng zusammen, deshalb würde ich sie auch nicht unbedingt in verschiedene Pakete packen, weil das eher eine Aussage ist, dass die Komponenten nicht zueinander gehören.  (Nur das Model würde ich  vom Rest abkoppeln).
Der Sinn von MVC ist eher eine sinnvolle Aufgliederung, um anfallende Änderungen an einer Komponente gezielter vornehmen zu können.

Aber deine Frage betrifft ja eigentlich nicht MVC, sondern es geht ja eher um Datenmodellierung. Und ja, ich würde es schon so machen, dass die Datenobjekte möglichst einfach sind. Also mit gettern, settern und listenern. Sonst sollten die nicht viel haben. Diese Objekte repräsentieren nur Daten und sind nicht für die Verarbeitung von Daten verantwortlich. Deinen Ansatz mit der Vererbung habe ich nicht ganz verstanden.
Und ich halte es für wichtig, hier etwas genauer zu planen, wie diese Datenobjekte untereinander in Beziehung stehen. Denn darauf baut sich der Rest des Programmes auf. Änderungen im Model haben auch fast immer Änderungen in der View und im Controller zur Folge, während das umgekehrt eher selten der Fall ist.

Um die Daten in der Datenbank abzuspeichern ist dieses Muster weit verbreitet:
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
Aber ich glaube, das brauchst du gar nicht.



> Und eine zweite Frage, wie mache ich die fehlerbehandlung bei meinem konzept, also hauptsächlich die, wenn es beim model zu fehlern kam, falscheingeb oder verbindung weg oder ähnliches



Das ist das klassische Aufgabengebiet des Controllers, diese Fälle zu behandeln. Das Model hat mit Benutzereingaben zunächst nix zu tun. Das läuft alles über den Controller. Der entscheidet, was Sinn macht und was er nicht durchlässt und ändert dann entsprechend das Model (über die getter und setter) oder eben auch nicht. Und die Views können sich wiederrum mit Listenern beim Model registrieren und werden benachrichtigt, wenn es sich geändert hat.


Also ich bin mir auch nicht sicher, ob ich MVC richtig verstanden habe. Kommentare sind wirklich erwünscht.


----------



## schalentier (7. Jul 2007)

Prinzipiell kannst du das machen wie du willst, wenn du eine klare Trennung zwischen Model (Daten), View (Sicht) und Controller (Verarbeitung) hast, isses auch MVC. Das Ding is da recht locker und laesst viele Freiheiten.

Ich wuerde das Model so feingranular (hehe) machen wie nur moeglich, also eine Klasse fuer Person, eine fuer Adresse, evtl. auch fuer Stadt und Land. Das alles dann per 1:1 oder 1:n Beziehungen verknuepfen. 

In die Modelklassen gehoeren dann die getter/setter fuer die ganzen Properties. Mit Listener is zwar schoen, dann kann man so Sachen realisieren wie, wenn irgendjemand am Model irgendwas aendert, wird automatisch die GUI aktualisiert. Das ist in der Tat schoen und auch wuenschenswert, aber nicht ganz trivial. Du solltest dir dann irgendeine Art Transaktionsmanagement fuer die Aenderungen einer Property ueberlegen, denn schnell gibts genau da Performanceengpaesse, wenn du naemlich viele Properties auf einmal aenderst, wird jedesmal ein Event zum View gefeuert, was dort ein Refresh verursacht. Bei vielen Propertyaenderungen sollte also auch nur einmal der View geupdated werden, sonst wirds frueher oder spaeter ziemlich lahm.

Ich wuerd auch den ganzen Validierungscode ins Model schieben. Evtl. is da was schickes mit Annotations zu machen:

```
public class Person {
    String name;
    Address address;

    public String getName() {
        return name;
    }

    @ValidateLength(50)
    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

    @ValidateNotNull()
    public void setAddress(Address address) {
        this.address = address;
    }
}
```

Ausserdem wuerde ich Logik-Methoden mit ins Model packen. Also irgendwelche Berechnungen zb. Der Vorteil waere dann, man kann das gesamte Model schick mittels UML planen und vor allem alles ohne Controller und View (also Abhaengigkeiten), getrennt testen (Unittests, funktionale Tests). 

Pro Modelklasse gibts dann mindestens einen View (Beispiel oben: PersonView, AddressView), ein Controller (z.b. ShowEditPersonController) erzeugt dann alle benoetigten Views, zeigt diese an und registriert sich als Listener bei den Views. Aenderungen propagiert er zum Model. Ohne Aenderungsevents vom Model aus, muss der Controller die Views zum refreshen auffordern (z.b. nach Klick auf Refreshbutton, oder zeitlich gesteuert oder sonstwie), die dann die notwendigen Daten aus dem Model holen. 

Zum Thema RMI: Damit hab ich noch nicht viel gemacht, ich wuerd aber ein Proxy vorschlagen. Auch hier gibts Tausend Moeglichkeiten, die offensichtlichste is in der Wikipedia erklaert (Person wuerde ein Interface werden, es gibt 2 Implementierungen: 1x normal wie oben, 1x ruft per RMI die Gegenseite auf und liefert das Ergebnis zurueck). Da haste nur ne Menge Tipparbeit, evtl. lohnt hier der Einsatz eines Codegenerators...; wieso eigentlich RMI, waere z.b. Hibernate nicht irgendwie einfacher?).

Errorhandling: Per Exception is einfach und sauber, bei groesseren Sachen aber inperformant. Sobald eine Exception geworfen wird, muss die komplette VM gestoppt werden, um den Stacktrace zu erzeugen. Das dauert, besonders wenn da oft Exceptions fliegen. Alternativ waere sowas in der Art denkbar:


```
public class BaseModel {
    List<String> errors = new ArrayList<String>();

    public void addError( String error ) {
        errors.add( error );
    }
    public boolean isValid() {
        return errors.size()==0;
    }
}

public class Person extends BaseModel {
    String name;
    public void setName(String name) {
        if( !validate( name ) ) { addError( "name ist ungueltig"); }
        else this.name = name;
    }
}
```

Sind alles nur flinke Ideen, ich hoffe is irgendwie nuetzlich ;-) Wichtig: Versuch nicht irgendwelche Probleme zu umschiffen, die du noch nicht hast. Damit kommste vom Hundertsten ins Tausendste und wirst nie fertig. Keep it simple!


----------

