MVC - Info an Änderung des Models

Status
Nicht offen für weitere Antworten.

Marcel_Handball

Bekanntes Mitglied
Moin,

ich habe mir das Tutorial zu MVC auf MVC - Sun durchgelesen.

Dort werden die Änderungen am Model an den Controller weitergegeben. Wann ist dies sinnvoll und wann sollten diese direkt an die Views geleitet werden?


Wenn ein Model mehrere Variablen hat und sich ein Wert ändert, wie kann ich der View mitteilen, welcher Wert sich geändert hat (sodass die View nicht alle Werte des Models neu darstellen muss).
Auf der Sun-Seite wird dies über Reflection gelöst. Ist dies die einzige Möglichkeit?
 

Painii

Bekanntes Mitglied
Java:
notifyObservers(Object o); //der Observer bekommt dann bei update(Observable arg, Object o) o!=null

Dem Model sollte egal sein wie Controller/View aussehen, das Model sagt einmal notifyObservers und sagt damit allen die es wissen wollen das sich was ändert.

Ob dann der Controller ein Observer ist oder nicht ist dann seine Sache. (Aber der Controller sollte ja das Model ändern - wenn er dann benachrichtigt wird das sich was geändert hat, was bringt das?)
 

Marcel_Handball

Bekanntes Mitglied
Ich kann zwar über notifyObservers(Object o); der View eine Information zukommen lassen, aber wenn das Model zum Beispiel über 5 int Werte verfügt und sich nur einer geändert hat, woher weiß die View in der Update Methode, welchen Wert sie neu darstellen muss?
(ohne sie alle 5 zu erfragen und neu anzuzeigen)
 

Painii

Bekanntes Mitglied
aber wenn das Model zum Beispiel über 5 int Werte verfügt und sich nur einer geändert hat

Ein Wrapper-Objekt übergeben mit dem der view eindeutig den int identifizieren kann, z.b. so:
Java:
public enum Irgendwas{
 Integer1, Integer2, Integer3;
}
public View implements Observer{
 public void update(Observable arg, Object o){
  Irgendwas i = null;
  if(o instanceof Irgendwas) i=(Irgendwas)o;
  switch(i){
   case Integer1: model.getInteger1(); break;
   case Integer2: model.getInteger2(); break;
   case Integer3: model.getInteger3(); break;
  }
}
Oder noch einfacher einfach alle Werte dem Wrapper übergeben (List) und dann die Werte die drin sind übertragen.


Wobei eigentlich der View nur die getMethoden aufruft, und da würde ich persönlich nicht viel Logik implementieren (-> kostengünstiger Aufruf -> kann man auch alle 5 Aufrufen).
 

Marco13

Top Contributor
Hmmm... ganz allgemein: Das Observer-Pattern ist praktisch ein "Teil" des MVC-Patterns - aber sehr speziell. Insbesondere macht es bei eigenen MVC-Strukturen IMHO meistens keinen Sinn, die Observer/Observable-Klassen von Java zu verwenden, weil sie eben genau solche Dinge nicht oder nur sehr unschön abbilden können. Man könnte zwar in den "args" beim notify irgendwas unterbringen, oder ganz pragmatisch bei jeder Änderung die ganze View updaten, aber das wäre beides IMHO nicht so hübsch.

Stattdessen solltest du in Erwägung ziehen, dein eigenes Modell (Observable) und dazu passende Listener (Observer) zu erstellen, und dazu passende Events (.... ja, das ist genau das, wozu es beim einfachen Observer/Observable keine Entsprechung gibt).

Also anstatt sowas zu machen
Java:
class CustomerModel extends Observable
{
    void buySomething() { /* Änderungen, dann ... */  notifyObservers(); }
    void sellSomething() { /* Änderungen, dann ... */  notifyObservers(); }
}

class CustomerView implements Observer
{
    private CustomerModel customerModel;

    void update()
    {
        // Bei JEDER änderung ALLES updaten
        boughtStuffList.updateWithDataFrom(customerModel);
        soldStuffList.updateWithDataFrom(customerModel);
    }

}

Könntest du das ganze "feingranularer" aufbauen:
Java:
interface CustomerModel
{
    void buySomething();
    void sellSomething();
    
    void addCustomerListener(CustomerListener cl);
    void removeCustomerListener(CustomerListener cl);
}

class DefaultCustomerModel implements CustomerModel
{
    // Default-Implementierung der obigen Methoden
}


interface CustomerListener
{
    void boughtSomething(CustomerEvent e);
    void soldSomething(CustomerEvent e);
}

class CustomerEvent
{
    public int getType() { /* liefert eine Konstante SOLD oder BOUGHT */ }
    public Object getTradedItem() { /* Liefert das ge- oder verkaufte Ding */ }
}


class CustomerView implements CustomerListener
{
    private CustomerModel customerModel;

    public void boughtSomething(CustomerEvent e)
    {
        // NUR das nötige updaten:
        boughtStuffList.add(e.getTradedItem());
    }

    public void soldSomething(CustomerEvent e)
    {
        // NUR das nötige updaten:
        soldStuffList.add(e.getTradedItem());
    }

}


Nur von der Idee her - die genaue Struktur musst du dir halt überlegen, aber wenn du dir mal die Klassen von Swing ansiehst, ist das eben so häufig so, dass man es schon fast als (Entwurfs-)Muster bezeichnen könnte ;) :

interface TableModel
class DefaultTableModel implements TableModel
interface TableModelListener
class TableModelEvent
class JTable (die View) implements TableModelListener

interface ListModel
class DefaultListModel implements ListModel
interface ListDataListener
class ListDataEvent
class JList (die View) implements ListDataListener

...
 
G

Gast2

Gast
Für sowas bietet sich der PropertyChangeListener
Das Model hat eine Liste aller PropertyChangeListener und feuert dann wenn sich was verändert hat die PropertyChangeEvent event, welche die View(s) dann auswerten kann/können...

Ach ist ja im Sun tutorial drin

Auszug:
Java:
public abstract class AbstractModel
{

    protected PropertyChangeSupport propertyChangeSupport;

    public AbstractModel()
    {
        propertyChangeSupport = new PropertyChangeSupport(this);
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.removePropertyChangeListener(listener);
    }

    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
        propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
    }


}
 
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
Hm. Ich hatte das auch gesehen, und hatte das Tutorial auch schonmal durchgepflügt, und im Dunstkreis dieses Tutorials hatte ich dann die Frage gestellt http://www.java-forum.org/allgemein...et-man-propertychangedevents-wann-eigene.html - die Antworten waren eher spärlich.

Plakativ formuliert: Man könnte ja IMMER und wirklich für ALLES PropertyChangedEvents verwenden - warum überhaupt noch eigene Listener/Events, wenn damit alles abgebildet werden kann? Oder noch weiter getrieben: Wie wäre es, wenn man alle Listener-Interfaces und Events "deprecated", und es nur noch eine Klasse
Code:
class Event
{
    public String whatHappened() { .... }
}
gibt, wo bei "whatHappened()" jeder das Reinschreiben kann, was er will?
 
G

Gast2

Gast
Hm. Ich hatte das auch gesehen, und hatte das Tutorial auch schonmal durchgepflügt, und im Dunstkreis dieses Tutorials hatte ich dann die Frage gestellt http://www.java-forum.org/allgemein...et-man-propertychangedevents-wann-eigene.html - die Antworten waren eher spärlich.

Plakativ formuliert: Man könnte ja IMMER und wirklich für ALLES PropertyChangedEvents verwenden - warum überhaupt noch eigene Listener/Events, wenn damit alles abgebildet werden kann? Oder noch weiter getrieben: Wie wäre es, wenn man alle Listener-Interfaces und Events "deprecated", und es nur noch eine Klasse
Code:
class Event
{
    public String whatHappened() { .... }
}
gibt, wo bei "whatHappened()" jeder das Reinschreiben kann, was er will?

Klingt doch gut ^^...
Nee ich würde mal sagen kommt auf die Größe des Projektes an...
Was hast denn für spärliche Hinweise bekommen?
 

Marco13

Top Contributor
Die "spärlichen" Antworten waren eben gerade die beiden in dem verlinkten Thread. Ich hatte eigentlich erwartet, dass da mehr Leute was dazu sagen können - ist ja eigentlich schon eine ziemlich allgemeine Frage....

EDIT: Und das mit der größe des Projektes ist so eine Sache: Projekte neigen dazu, nicht ihr Leben lang gleich groß zu bleiben - und bei einem Projekt mit 100 Klassen NUR PropertyChangeListener zu verwenden, und sobald es 110 Klassen sind alles auf Tysichere, dedizierte Listener umzustellen ist ja nicht praktikabel....
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
berserkerdq2 Wenn ich bei Intelij javafx mit maven importieren will, muss ich das in die pom.xml reintun, aber warum noch in module-info.java? Allgemeine Java-Themen 3
I Module-Info für Jar erzeugen Allgemeine Java-Themen 7
M ist in der Module-Info "opens PACKAGENAME" bedenklich? Allgemeine Java-Themen 0
looparda Best Practice Jigsaw module-info.java Allgemeine Java-Themen 1
M Klassen Info-Center - Namensänderung & permanentes "behalten" Allgemeine Java-Themen 5
S Info bei Datenänderung Allgemeine Java-Themen 18
R RXTX Versions Info abschalten Allgemeine Java-Themen 6
G JNDI Info Allgemeine Java-Themen 2
G Wie kriegt Klasse2 die Info, was Klassse1 gerade "macht Allgemeine Java-Themen 7
egrath Info über VM Architektur Allgemeine Java-Themen 2
K log4j - eigene Info-Ausgaben Allgemeine Java-Themen 5
S Vector sortieren nach Objekt-Info? Allgemeine Java-Themen 9
S Log4J mit 2 Appender, einer soll nur INFO loggen Allgemeine Java-Themen 3
R Wo müsste ich im Code eine Änderung vornehmen? Allgemeine Java-Themen 6
H Änderung im maximalen heap space unter Windows 7 ?! Allgemeine Java-Themen 5
O Fragen über Fragen - Bei Änderung XML-Datei -> Anpassung GUI Allgemeine Java-Themen 7
S Änderung in einer Datei Allgemeine Java-Themen 7
G Input/Output Manuelle Änderung von Wert in Swing Komponente bemerken! Allgemeine Java-Themen 2
F Änderung in .jar bzw. .class vornehmen ? Allgemeine Java-Themen 18
Iron Monkey JNLP nach Änderung automatisch aktualisieren Allgemeine Java-Themen 18
G Änderung eines primitiven Datentyps löst Fehler aus Allgemeine Java-Themen 7
N Änderung des Objektnamens Allgemeine Java-Themen 3
M jdesktop binding: jTable update nach Änderung... Allgemeine Java-Themen 3
T Eingebettes Objekt über Änderung d. äußeren Obj. informieren Allgemeine Java-Themen 4
J Nach SOAP Protokollierungen Änderung vornehmbar? Allgemeine Java-Themen 2
S Änderung an Proberties datei an alle User weitergeben? Allgemeine Java-Themen 7
E Listener für Änderung der Fenstergröße Allgemeine Java-Themen 3
W Listener an ein beliebiges Objekt hänger, der mir Änderung Allgemeine Java-Themen 8
X Registrierung eines Ecore-Models außerhalb der Eclipse-Umgebung Allgemeine Java-Themen 0
G Models EventHandling Allgemeine Java-Themen 14
m@nu Programm-Models in Static-Objekten speichern Allgemeine Java-Themen 5

Ähnliche Java Themen


Oben