# Ganz einfaches MVC-Beispiel?!



## Verjigorm (26. Mrz 2009)

Hallo,
ich soll hier einem ganz blutigem Anfänger erklären, was man unter MVC versteht.
Hab dann erstmal im Netz nach ganz einfachen Beispielen gesucht, aber wie ich finde, waren die meist schon zu kompliziert, da oft auch Interfaces, Observer/Observable mit im Spiel waren.

Ich hab mir dann einfach selbst schnell was aus den Fingern gesagt, aber irgendwie find ich es überhaupt nicht toll 

Wobei ich mich auch grade gefragt habe, ob ihr auch die packages view/model/controller benutzt oder wie.

Was haltet ihr denn davon:
View:

```
package view;

import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JComboBox;

public class View extends JFrame {

    private static final long serialVersionUID = 1L;
    private JPanel jContentPane = null;
    private JButton jButton = null;
    private JComboBox jComboBox = null;

    /**
     * This is the default constructor
     */
    public View() {
        super();
        initialize();
    }

    /**
     * This method initializes this
     * 
     * @return void
     */
    private void initialize() {
        this.setSize(300, 200);
        this.setContentPane(getJContentPane());
        this.setTitle("JFrame");
    }

    /**
     * This method initializes jContentPane
     * 
     * @return javax.swing.JPanel
     */
    private JPanel getJContentPane() {
        if (jContentPane == null) {
            jContentPane = new JPanel();
            jContentPane.setLayout(new BorderLayout());
            jContentPane.add(getJButton(), BorderLayout.CENTER);
            jContentPane.add(getJComboBox(), BorderLayout.SOUTH);
        }
        return jContentPane;
    }

    /**
     * This method initializes jButton    
     *     
     * @return javax.swing.JButton    
     */
    public JButton getJButton() {
        if (jButton == null) {
            jButton = new JButton();
            jButton.setText("Klick Mich");
        }
        return jButton;
    }

    /**
     * This method initializes jComboBox    
     *     
     * @return javax.swing.JComboBox    
     */
    public JComboBox getJComboBox() {
        if (jComboBox == null) {
            jComboBox = new JComboBox();
        }
        return jComboBox;
    }

}
```
Model:

```
package model;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class Model 
{
    private static final String message = "Ein einfaches MVC-Beispiel am:\n";
    private static final Date today = new Date();
    private final List<String> listItems = new ArrayList<String>();

    public Model() 
    {
        listItems.add("Eins");
        listItems.add("Zwei");
        listItems.add("Drei");
        listItems.add("4");
        listItems.add("365");
    }
    /**
     * @return the message
     */
    public String getMessage() {
        return message;
    }

    /**
     * @return the today
     */
    public String getToday() {
        return new SimpleDateFormat("dd.MM.yyyy").format(today);
    }

    /**
     * @return the listItems
     */
    public List<String> getListItems() {
        return listItems;
    }
}
```
Controller:

```
package controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
import view.View;
import model.Model;

public class Controller {

    private final Model model = new Model();
    private final View view = new View();
    
    public Controller() 
    {    
        view.getJButton().addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) 
            {
                JOptionPane.showMessageDialog(view, model.getMessage()
                        + model.getToday());
            }
            
        });
        
        for(String item : model.getListItems())
        {
            view.getJComboBox().addItem(item);
        }
        
        view.setVisible(true);
    }
}
```
Main:

```
package main;

import controller.Controller;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) 
    {
        new Controller();
    }

}
```
mfg Verjigorm


----------



## SlaterB (26. Mrz 2009)

vor dem Beispiel sollte aber erstmal die Definition feststehen,
ich halte ja generell nicht so viel von festen Pattern, aber wenn ich mir den ersten google-Treffer zu MVC anschaue,
Model View Controller ? Wikipedia

dann steht da beispielsweise 
"Das Modell enthält die darzustellenden Daten und gegebenenfalls (abhängig von der Implementation des MVC-Patterns) auch die Geschäftslogik. Es ist von Präsentation und Steuerung unabhängig. Die Bekanntgabe von Änderungen an relevanten Daten im Modell geschieht nach dem Entwurfsmuster „Beobachter“."

dein Modell halte ich nicht für ein Modell, das ist mit dem View überhaupt nicht verknüpft,
du erstellst die String-Daten zwar in einer separaten Klasse, danach werden sie aber in die JComboBox kopiert,

die model.Model-Klase ist danach obsolet, könnte neue Strings aufnehmen oder aus der JVM ausradiert werden, 
das interessiert die View-JComboBox überhaupt nicht, die hat ihre eigenen Daten (kopiert)

wenn du dagegen ein ComboBoxModel schreiben würdest, das über Listener mit der JComboBox verknüpft ist, ja dann..


ein Controller, der nur ein JFrame zusammenbaut und sich nicht etwa um Aktionen der View (Button-Klicks) kümmert,
ist meiner Meinung nach auch nix echtes, die View kennt hier den Controller gar nicht (!),

wenn man 50% wegläßt, dann ist das vielleicht ein schön einfaches Beispiel, aber kann dann doch nicht MVC darstellen/ erklären 
(edit: ok, Button ist drin, bisschen zu kurz draufgeschaut  )


----------



## Geeeee (26. Mrz 2009)

Finde es ok, aber den "reinen" Konstruktoraufruf etwas unschön, um das Programm losrödeln zu lassen. Evtl. für die bessere Übersicht im Controller eine init-methode für das Hinzufügen der Komponenten und start-Methode für das setVisible() (es ist irgendwie sinnentfreit, aber finde ich persönlich schöner für einen Anfänger).
Evtl. sogar die Instanziierung von Model und View in den Konstruktor schieben, weil du ja von einem _blutigen_ Anfänger sprichst.
Edit: gerade nochmal genauer hingeschaut, weil ja noch ein Eintrag vor mir "dazwischen" kam: Es wäre schon hilfreich wenn du: view.getJButton().addActionListener(this) einfügst und der Controller die actionPerformed abarbeitet.


----------



## Verjigorm (26. Mrz 2009)

@Slater:
Das mit dem ComboBoxModel hatte ich mir überlegt, aber wie gesagt, dass ist ein Informatikstudent im 2.Semester, der schlackert eh schon mit den Ohren, wenn ich ihm gleich 4 Klassen vorlege, da wollte ich nicht noch mit Interfaces, Oberklassen und irgendwelchen festen Modells kommen.

Aber ich glaube es wird nicht anders funktionieren, sonst kann man damit wohl doch kein MVC mehr erklären.

edit: Naja ich hab ihm erstmal Eclipse gezeigt, der hat bisher im Texteditor programmiert, damit ist er mal sicher einige Stunden/Tage beschäftigt


----------



## Marco13 (26. Mrz 2009)

SlaterB hat gesagt.:


> vor dem Beispiel sollte aber erstmal die Definition feststehen,
> ich halte ja generell nicht so viel von festen Pattern, ...



Ja, neulich habe ich auch mal nach einer _verbindlichen_ Definition von MVC gesucht. Nur indirekt in bezug auf eine "feste Struktur", sondern vielmehr in bezug auf die tatsächlichen _Verantwortlichkeiten_ der einzelnen Klassen. Und nach langer Suche bin ich zu dem Schluss gekommen: Das gibt's nicht. Das kann man machen, wie man will  Im spziellen bezog sich meine Recheche auf den Controller...:



SlaterB hat gesagt.:


> ein Controller, der nur ein JFrame zusammenbaut und sich nicht etwa um Aktionen der View (Button-Klicks) kümmert,
> ist meiner Meinung nach auch nix echtes, die View kennt hier den Controller gar nicht (!),



Dann würde mich mal interessieren, was deiner Meinung nach ein "echter" Controller ist. In bestimmten (speziell Web-bezogenen) Anwendungen kann ein Controller tatsächlich ein echter "Mediator" sein, der sich um die _gesamte_ Kommunikation kümmert, und z.B. die Daten in beide Richtungen über's Netztwerk schaufelt oder so. Aber in einer "normalen" Anwendung ist _ein_ Controller _in dieser Form_ IMHO sinnlos: Wenn man einen Controller hat, der 50 Listener-Interfaces implementiert, und 1:1 mit der View verdengelt ist, und nichts anderes macht, als Anfragen von der View ans Modell weiterzureichen, bringt er keinen Vorteil, sondern nur Nachteile. Bestätigt wurde diese (meine) Ansicht durch einen Haufen Seiten, auf denen vermeintliche Experten ihre Interpretation des MVC-Pattens mit konstruiert-gekünstelten Suggestivbeispielen zu verdeutlichen versuchten, die nichts (aber auch garnichts) mit realen Anwendungen zu tun hatten, und durch scheinbar banale Fragestellungen, die mit ausufernden Diskussionen benatwortet wurden, wie etwa unter Whatsa Controller Anyway (und etwas ähnliches steht uns vermutlich auch hier bevor  )

Ich bin inzwischen der Meinung, dass es in (nochmal: Nicht Web-basierten) Anwendungen häufig nicht "einen Controller" gibt, sondern dass jeder (möglicherweise anonyme) Listener, der an irgendeinem Button hängt (und der - ja - auch direkt in der View-Klasse stehen kann!) ein "kleiner Controller" ist.


----------



## SlaterB (26. Mrz 2009)

'ein Controller' muss ja nicht 'eine Java-Klasse' bedeuten, mehrere Listener können das genauso sein, wenn man Controller eher als eine bestimmte Schicht in der Verarbeitung ansieht,

was der/ die nun für Aufgaben, hmm, ist doch nicht mein Thread hier 
lose überlegt und mit dem Wiki-Text verglichen:
der Controller ist NICHT die View, sondern was anderes,

nach Wiki "Sie [die Steuerung (Controller)] enthält weiterhin Mechanismen, um die Benutzerinteraktionen der Präsentation einzuschränken."
wäre ein solcher Einbau kein Grund, eine JTable zu überschreiben, sondern eine neue Basisklasse für (potentiell viele) Listener zu erstellen, 
die auf Ereignisse reagieren und nun vielleicht erstmal schauen ob die stadardisierte Aktion erlaubt ist

--------

der Controller ist derjenige, der die Info erhält, dass Daten X neu zu laden sind, 
dann irgendwo her die Daten holt, sie in Model Y schreibt, den Focus auf Textfeld Z legt und die Hintergrundfarbe von Statusfeld W ändert,
sowas macht keine JTable, hat ja auch keine Möglichkeiten dafür,

ob nun die Listener anonyme innere Klassen sind, die eigene JFrame-Unterklasse selber ActionListener implementiert oder ob es separate Klassen (eine oder mehrere) dafür gibt, 
ist eine Frage der Organisation und der Doppelimplementation von Aufgaben, da kann sicher vieles falsch und schöner machen,
durch Listener + Models ist aber der MVC-Grundgedanke in Swing meist gar nicht zu vermeiden


----------



## Marco13 (26. Mrz 2009)

SlaterB hat gesagt.:


> nach Wiki "Sie [die Steuerung (Controller)] enthält weiterhin Mechanismen, um die Benutzerinteraktionen der Präsentation einzuschränken."
> wäre ein solcher Einbau kein Grund, eine JTable zu überschreiben, sondern eine neue Basisklasse für (potentiell viele) Listener zu erstellen,
> die auf Ereignisse reagieren und nun vielleicht erstmal schauen ob die stadardisierte Aktion erlaubt ist



Hm - das mit der (nicht zu) überschreibenden JTable kann ich jetzt nicht ganz einordnen. Aber bei Swing hat man ja das klassische Beispiel, wo beim MVC einfach mal der C weggelassen wurde. Die Aussage "der Controller ist NICHT die View, sondern was anderes," stimmt daher nur ... bedingt .. eben nur, wenn es so ist, aber es kann auch anders sein  Bei einem Slider wird es deutlicher als bei einer JTable: Wenn man am Slider zieht, ändern sich die Werte des BoundedRangeModels. Der Slider ist demnach View UND Controller (oder nach meiner Definition: Der MouseMotionListener, der im Slider versteckt ist, ist der Controller)


----------



## Wildcard (26. Mrz 2009)

Alle Swing Objekte sind eigentlich Controller und die Trennung existiert dort, ist aber nicht sofort ersichtlich (und an manchen Stellen natürlich, wie bei fast jedem MVC, verwaschen).
Die JComponents sind Controller. Sie 'besorgen' sich die jeweiligen UI Klassen in Abhängigkeit des Look'n'Feels, welche die View repäsentieren. 
Man kann das Messer auch etwas weiter oben ansetzen und sagen: Die Renderer sind die View.


----------



## Marco13 (26. Mrz 2009)

Das mit dem "Messer weiter oben ansetzen" ist ein wichtiger Punkt (den hatte ich schonmal in einem der anderen MVC-Threads betont) : Die Klassen übernehmen ja bestimmte Rollen. 

Man könnte sagen: Ein JSlider ist kein Controller, sondern eine View - schließlich "ist er etwas, was gezeichnet wird" - dass das painting an das UI delegiert wird, sieht man ja von außen nicht.

Man könnte auch sagen: Ein JSlider ist ein Controller, das SliderUI ist die View, das BoundedRangeModel ist das Model. 

Aber wenn man das Messer (in diesem Sinne) weiter unten ansetzt, ist ein JSlider kein Controller, sondern doch wieder eine View, in der man eine Eigenschaft seines eigenen Datenmodells anzeigt. (Das "Modul" bestehend aus JSlider, SliderUI und BoundedRangeModel übernimmt bei gröberer Abstraktion die Rolle einer View). 

Es ist eben schwierig, View und Controller voneinander zu trennen, und Zuständigkeiten klar zuzuweisen. Ich fand meine Odyssee durch die verschiedenen MVC-Beispiel-Seiten irgendwie ... fast schon "frustrierend".... Überzogen formuliert: MVC ist das hochgelobte Universalpattern ... bei dem aber zu 1/3 unklar ist, was es eigentlich ausmacht....  Diese anderen 2/3 sind aber umso wichtiger: Das Modell sollte eigentständig und "isolierbar" sein. Den Rest können View und Controller unter sich ausmachen ...


----------



## Wildcard (26. Mrz 2009)

Marco13 hat gesagt.:


> Das mit dem "Messer weiter oben ansetzen" ist ein wichtiger Punkt (den hatte ich schonmal in einem der anderen MVC-Threads betont) : Die Klassen übernehmen ja bestimmte Rollen.
> 
> Man könnte sagen: Ein JSlider ist kein Controller, sondern eine View - schließlich "ist er etwas, was gezeichnet wird" - dass das painting an das UI delegiert wird, sieht man ja von außen nicht.


Richtig. Swing Intern ist ein JSlider keine View, für mich, als Client, allerdings schon.



> Es ist eben schwierig, View und Controller voneinander zu trennen, und Zuständigkeiten klar zuzuweisen. Ich fand meine Odyssee durch die verschiedenen MVC-Beispiel-Seiten irgendwie ... fast schon "frustrierend".... Überzogen formuliert: MVC ist das hochgelobte Universalpattern ... bei dem aber zu 1/3 unklar ist, was es eigentlich ausmacht....  Diese anderen 2/3 sind aber umso wichtiger: Das Modell sollte eigentständig und "isolierbar" sein. Den Rest können View und Controller unter sich ausmachen ...


Ja, dem kann ich zustimmen. Ich habe bisher eigentlich nur sehr wenige real life Beispiele gesehen, bei denen die View/Controller Trennung sauber durchgezogen wird. Meistens verschmelzen View und Controller auf die eine oder andere Art.
Wenn du dich aber für ein solches Interessierst, schau dir GEF an. Wirklich interessante Sache. 

Wie die Trennung praktisch umgesetzt wird ist hier beschrieben:
GEF Description - Eclipsepedia


----------



## Marco13 (26. Mrz 2009)

Wildcard hat gesagt.:


> Ich habe bisher eigentlich nur sehr wenige real life Beispiele gesehen, bei denen die View/Controller Trennung sauber durchgezogen wird. Meistens verschmelzen View und Controller auf die eine oder andere Art.



"Sauber" - das klingt jetzt aber wieder, als sei es irgendwie besonders erstrebenswert, die beiden komplett zu trennen. Abgesehen von den schon erwähnten Ausnahmen (Web-Zeux und Spezialfälle) sehe ich im allgemeinen keinen Grund, das zu tun. Es ist im allgemeinen kaum praktikabel, das umzusetzen, und erfordert viel Aufwand und bringt IMHO keinen Vorteil...

Aber vielleicht ändert sich meine Ansicht dazu ja noch - das mit dem GEF werd' ich mir auf jeden Fall mal :rtfm: en.


----------



## Wildcard (26. Mrz 2009)

Marco13 hat gesagt.:


> "Sauber" - das klingt jetzt aber wieder, als sei es irgendwie besonders erstrebenswert, die beiden komplett zu trennen. Abgesehen von den schon erwähnten Ausnahmen (Web-Zeux und Spezialfälle) sehe ich im allgemeinen keinen Grund, das zu tun. Es ist im allgemeinen kaum praktikabel, das umzusetzen, und erfordert viel Aufwand und bringt IMHO keinen Vorteil...


Ja... für die normale GUI bin ich mir auch nicht sicher ob das wirklich erstrebenswert ist. Aber du verstehst schon was ich mit sauber getrennt meine, also lassen wir es dabei 
GEF ist allerdings primär für grafische Editoren gedacht, hautpsächlich Diagramme.
Ich sag mal so, ich habe jahrelang an einem solchen grafischen Editor gearbeitet in dem Model View und Control zu einem Wollknäul verschmolzen sind und dann weißt du ein 'sauber' getrenntes Framework doch sehr zu schätzen.
Im Falle von Diagrammen halte ich die konsequente Trennung für absolut sinnvoll. Bei Widget basierten GUIs... wer will da schon päpstlicher als der Papst sein.


----------



## André Uhres (27. Mrz 2009)

Ich finde das Beispiel auch OK, ausser eben die Modelgeschichte.
Das könnten wir aber leicht anpassen, etwa so:

```
public class Model {
...
    private DefaultComboBoxModel listItems = new DefaultComboBoxModel();
    public Model() {
        listItems.addElement("Eins");
        listItems.addElement("Zwei");
...
    public DefaultComboBoxModel getListItems() {
        return listItems;
    }
}
```


```
public class Controller {
...
    public Controller() {
...
        view.getJComboBox().setModel(model.getListItems());
...
```


----------



## Gast2 (27. Mrz 2009)

Servus,

wenn so ein Thema schon mal diskutiert wird würde ich gern mal die Meinung zu so einem Aufbau hören. Was man besser/geschickter machen kann. Und ob ich eventuell grundsätzlich etwas falsch verstanden hab.

View mit main:
[HIGHLIGHT="Java"]
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTextField;

public class View extends JFrame implements PropertyChangeListener {

    private JTextField txtEingabe;
    private JComboBox cAusgabe;
    private JButton button;
    private Controller controller;

    public View(Controller c) {
        super("MVC Beispiel");
        this.controller = c;
        controller.addListener(this);
        txtEingabe = new JTextField(30);
        cAusgabe = new JComboBox();
        button = new JButton("Hinzufügen");
        add(txtEingabe, BorderLayout.NORTH);
        add(cAusgabe, BorderLayout.CENTER);
        add(button, BorderLayout.SOUTH);
        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                controller.addItem(txtEingabe.getText());

            }

        });
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public void propertyChange(PropertyChangeEvent evt) {
        if (evt.getPropertyName().equals(Controller.ITEMS_CHANGE)) {
            List<String> newValue = (List<String>) evt.getNewValue();
            cAusgabe.setModel(new DefaultComboBoxModel(newValue.toArray()));
        }

        if (evt.getPropertyName().equals(Controller.ADD_ITEM)) {
            String newValue = (String) evt.getNewValue();
            cAusgabe.addItem(newValue);
        }

    }

    public static void main(String[] args) {
        Controller contoller = new Controller();
        new View(contoller);
    }

}

[/HIGHLIGHT]

Controller

[HIGHLIGHT="Java"]
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.List;

public class Controller {

    public static final String ITEMS_CHANGE = "itemchange";
    public static final String ADD_ITEM = "itemadd";
    private Model model;
    private PropertyChangeSupport listeners = new PropertyChangeSupport(this);

    public Controller() {
        model = new Model();
    }

    public void setItems(List<String> items) {

        List<String> old = getItems();
        if (old.equals(items)) {
            model.setItems(items);
            firePropertyChange(new PropertyChangeEvent(this, ITEMS_CHANGE, old, items));
        }
    }

    public List<String> getItems() {
        return model.getItems();
    }

    public void addItem(String item) {
        model.addItem(item);
        firePropertyChange(new PropertyChangeEvent(this, ADD_ITEM, null, item));
    }

    public void addListener(PropertyChangeListener listener) {
        listeners.addPropertyChangeListener(listener);
    }

    public void removeListener(PropertyChangeListener listener) {
        listeners.removePropertyChangeListener(listener);
    }

    public void firePropertyChange(PropertyChangeEvent event) {
        listeners.firePropertyChange(event);
    }

}

[/HIGHLIGHT]

[HIGHLIGHT="Java"]
import java.util.ArrayList;
import java.util.List;


public class Model {

    private List<String> items;

    public Model()
    {
        setItems(new ArrayList<String>());
    }

    public void setItems(List<String> items) {
        this.items = items;
    }

    public void addItem(String item)
    {
        items.add(item);
    }

    public List<String> getItems() {
        return items;
    }
}


[/HIGHLIGHT]


----------



## SlaterB (27. Mrz 2009)

meiner Ansicht nach ist dein Controller komplett noch Model,
es macht zwar Sinn, zwischen reinen Daten aller höchstens mit ner Collection und einem Ding zur Verwaltung von Listenern und Events zu unterscheiden,
aber dafür gibts ja ComboBoxModel & Co., und das sind Model, wie der Name schon sagt,

wirklich Controller ist Zeile 34 im View-Codeblock

Zeile 44-55 im View ist was seltsames zwischen Model und View, was normalerweise eine JTable zum TableModel schon automatisch kann,

je nach Abstraktionsebene (View ist nur der Renderer) verschiebt sich natürlich die Interpretation


----------



## Gast2 (27. Mrz 2009)

ok ich mache mit den daten ja nichts spannendes ...
aber das model könnte ja noch geschäftslogik enthalten oder die daten auswerten...
Klar gibt es ein ComoboxModel, aber ich dachte so hab ich ein "reines" Datenmodel
und wenn ich mehrer Panels(Views) hätte, die gleichen Daten benutzen und anderst darstellen, können alle Views diese benutzen oder wie würdest du sowas machen???
und Zeile 44-55 wie würdest du die View benachrichtigen, dass sich das Model gändert hat???
Wär echt cool wenn mal ein paar erfahrene Programmierer sagen könnten wie Sie das in ihre Projekte so realisieren =)...
Weil ich hab auch schon gesehen, dass das Model die Listener aufnimmt und die Event verschickt wenn es sich geändert hat, bei anderen macht es der Controller usw.
Wie ist des denn eigentlich üblich???:rtfm:

Gruß


----------



## SlaterB (27. Mrz 2009)

es spricht ja nix gegen diese Trennung/ Eigenprogrammierung, 
wenn es Swing-Models nicht gäbe, dann ist es ja nicht verboten sie zu erfinden 

> können alle Views diese benutzen oder wie würdest du sowas machen???

ich hab das kürzlich mal gemacht und mir den coolen Begriff MetaModel ausgedacht, ein MetaModel hat mehrere normale Swing-Model als Listener, die wiederum ihre Views informieren, siehe auch
http://www.java-forum.org/awt-swing-swt/80557-jlist-jtree-jtextarea-daten-refresh.html
(wenn auch von mir da nicht viel steht)
(edit: aber du hast in dem Thema auch schon gepostet  )

deinem Controller gar nicht unähnlich, man müsste die Klasse nur umbenennen

und die Daten ins ComboBoxModel zu kopieren ist dann meiner bescheidenen Meinung nach redundant, 
lieber ein neues ComboBoxModel schreiben, welches bei getSize() die aktuelle Länge des MetaModels abfragt,
bei getElementAt(int index) auch beim MetaModel nachfragt usw., 
ein leeres Model, welches nur das MetaModel kapselt und dessen Änderung-Events in die andere Richtung übersetzt und weiterleitet


----------



## Gast2 (27. Mrz 2009)

> (edit: aber du hast in dem Thema auch schon gepostet  )



ja aber bei dem Adapter bin ich dann ausgestiegen, weil ich nicht genau wusste was damit gemeint war bzw. wie es gemeint war die zu realisieren


----------



## Marco13 (27. Mrz 2009)

André Uhres hat gesagt.:


> Ich finde das Beispiel auch OK, ausser eben die Modelgeschichte.
> Das könnten wir aber leicht anpassen, etwa so: ...


[s.o.]

Also DAS kapier' ich jetzt nicht ???:L (Ehrlich gesagt bin ich sogar SEHR irritiert, dass DU das so vorschlägst... ???:L ). 

Wenn überhaupt, dann würde man da sicher kein DefaultComboBoxModel zurückgeben, sondern ein ComboBoxModel. Das kann noch ein Copy&Paste-Fehler sein, aber ... meine Irritation bezieht sich auf einen viel allgemeineren Punkt: Wenn man sein eigenes Model schreibt, dann ist es doch (zurückhaltend formuliert...) unzweckmäßig, sich auf ein Swing-Model zu stützen. Wenn das ganze dann mal in einer JList dargestellt werden soll, was soll man dann machen? Das ComboBoxModel in ein ListModel ändern? Eine Implementierung von ListModel anbieten, die an ein ComboBoxModel delegiert? Häm... ne, ich versteh' das gerade nicht ... :bahnhof:


----------



## SlaterB (27. Mrz 2009)

nur für die Möglichkeit, dass es mal auch auf einer JList dargestellt werden soll, soll man sich vorsorglich die Arbeit eines eigenen Models machen?
welchen Sinn hat das denn

man kann doch dann anpassen, wenn es dazu kommt, wieso vorher?
zudem in einem einfachen Beispiel doch sehr deplaziert (ups, SirWayne hat das ja auch  )

> Wenn man sein eigenes Model schreibt

macht ja keiner, falls du nicht eine simple Klasse, die ein DefaultComboBoxModel enthält, schon als eigenes Model ansiehst,
auf diese recht leere Klasse kann man sicherlich verzichten und nur das ComboBoxModel irgendwo speichern, 
denkbar,

aber wenn es wie im Ursprungsbeispiel zusätzlich noch den String + das Datum enthält, dann ist das eben eine Art Sammelstelle für mehrere Model
(wobei String + Datum ganz andere Arten von Model sind ohne Listener usw., das ist ein Thema für sich)


----------



## Gast2 (27. Mrz 2009)

ja aber ich sehe es bis jetzt auch so wie Marco...
Da es sich um ein einfaches Beispiel handelt sollte man jetzt nicht auf dem einfachen Model rum "nörgeln"...
Wenn ich die Liste in verschiedenen Komponenten oder sonstigen Views angezeigt werden sollen wieso dann auf ein SwingModel beziehen... in dem model könnten ja auch z.B. noch Berechnungen für irgendwelche Statistiken gemacht werden usw. oder???

Aber ich weiß immer noch nicht wie du es bewerkstelligen willst, wenn sich dein Model ändert, dass die Views das mitbekommen wenn du meine Listener geschichte nicht so gut fandest?? 
Könnte mal jemand was posten wie man es auch anders machen könnte, würde mich interessiert ...


----------



## SlaterB (27. Mrz 2009)

wo habe ich denn geschrieben, dass ich deine Listener-Geschichte nicht gut finde?
ohne Listener gehts nicht, für ein Model für mehrere Views schon gar nicht, was ich allerdings als Eingangsbeispiel etwas übertrieben finde,

wenn man nur ein View und ein Model hat, dann sind eigene Listener + Events statt  DefaultComboBoxModel etwas merkwürdig, aber nicht unbedingt falsch, 
eigene Listener, die dann doch nur ein DefaultComboBoxModel befüllen noch seltsamer doppelt gemoppelt,
das könnte man vielleicht als 'nicht gut von mir bewertet' interpretieren, ok 

dass das im Sinne von ein Model für mehrere Views wiederum ok ist, habe ich aber geschrieben:
> deinem Controller gar nicht unähnlich, man müsste die Klasse nur umbenennen


----------



## Gast2 (27. Mrz 2009)

> wo habe ich denn geschrieben, dass ich deine listener-geschichte nicht gut finde?
> ohne listener gehts nicht, für ein model für mehrere Views schon gar nicht, was ich allerdings als Eingangsbeispiel etwas übertrieben finde


Ja ich finde wenn man schon MVC erklärt sollte man das listener konzept schon anschlagen da bei der GUI Komponenten z.B. JButton gar nichts funktioniert ...

Ok das andere habe ich wohl missverstanden  ...

1.Aber wie macht ihr das lasst ihr eurem controller events schicken oder macht ihr das direkt im Model????
2. bei dem 1. Beispielt instanziert er die view im controller und benutzt dort auch die Swing komponenten mit weiteren Listener... ist doch ziemlich unpratikabel oder?
3. hätte ich noch ne arichtektur frage ... wenn ihr ein controller, welcher die listener added, habt und mehrer views... macht ihr euren controller dann statisch oder übgebt ihr ihm konstruktor???

irgendwie beteiligen sich bis jetzt wenig an diesem thema :bae:...
hab gehofft man bekommt paar arichtektur tipps von unseren "Java Gurus" ...


----------



## Marco13 (27. Mrz 2009)

SlaterB hat gesagt.:


> nur für die Möglichkeit, dass es mal auch auf einer JList dargestellt werden soll, soll man sich vorsorglich die Arbeit eines eigenen Models machen?
> welchen Sinn hat das denn
> 
> man kann doch dann anpassen, wenn es dazu kommt, wieso vorher?
> ...



Ich kapier das gerade echt nicht ???:L 

Man modelliert irgendwas. Als Dummy-Beispiel eine Liste für Namen und Geburtsdaten. Das Modell sollte KOMPLETT unabhängig von der View sein. Wenn man das Modell schreibt, muss man vergessen können, dass es Swing überhaupt gibt. Darum (und man könnte sagen: *NUR* darum) geht es doch bei MVC eigenttlich - das ist doch (zumindest nach meinem Verständnis) Sinn und Kern des ganzen Patterns.

Man definiert also für diesen Fall das (und genau das) was mit dem Modell gehen soll.

```
interface Model
{
    int getNumPersons();
    Date getDate(int i);
    String getName(int i);
    ..
}
```
Und im Iedalfall sollte sich dieses interface nie mehr ändern. 

Das Modell ist jetzt fertig modelliert. Es kann das (und genau das) was es können soll. Es ist das (und genau das) modelliert, was das Modell ausmacht. 

So. Weil du das auch immer machst  hier mal eine Trennlinie:

---------

Jetzt kommt der zweite Teil: Die View(s)

Man schreibt eine View, die ein Modell bekommt (das interface, bei dem sie sich darauf verlassen kann, dass es im Idealfall immer so bleiben wird, wie es ist). Diese View stellt die Daten aus dem Modell dar.

Wenn man das oben beschriebene Modell in zwei ComboBoxes darstellen will, wäre es natürlich "bequem" und "praktsich", wenn man die Daten als zwei ComboBoxModels bekommen würde. Aber die View muss sich am Modell orientieren, und nicht umgekehrt. Sich dann "grundlos" im Modell auf etwas festzulegen, was mit dem _abstrakten Gebilde_ das ein Datenmodell darstellt, nichts zu tun hat, nur weil das für eine bestimmte View-Implementierung "praktisch" ist, kann ja nicht das Ziel sein.

Ein Problem hätte man dann spätestens, wenn es mehrere Views gibt, die das ganze dann
- in zwei ComboBoxes
- in einer ComboBox(!)
- in einer JList
- und in einer JTable
darstellen wollen: wie soll man da dann das "passende" Swing-Modell reinpfriemeln? Das gibt es nicht. Aber für das oben beschriebene, allgemeingültige Modell kann man mit minimalem Aufwand ComboBoxModels, ListModels und TableModels schreiben, die das echte Modell als Delegate verwenden. Dass es prinzipiell möglich wäre, mehrere ListModels zu einem TableModel zusammenzuwursten hatte ich ja schon erwähnt, aber sich bei der Beschreibung des Modells an einer "bevorzugten" oder "im ersten Moment sinnvoll erscheinenden" View zu orientieren erscheint mir fragwürdig ???:L


----------



## SlaterB (27. Mrz 2009)

alles schon bekannte Themen, ich will nicht auf alles durcheinander antworten und gar wiederholend, daher zum einen nur kurz zwei Zitate:


SlaterB hat gesagt.:


> es macht zwar Sinn, zwischen [zum einen] reinen Daten allerhöchstens mit ner Collection und [zum anderen] einem Ding zur Verwaltung von Listenern und Events zu unterscheiden,
> aber dafür gibts ja ComboBoxModel & Co., und das sind Model, wie der Name schon sagt,


> Das Modell ist jetzt fertig modelliert

zum Model gehört auch Benachrichtigung über Änderungen,
gerne in zwei unterschiedlichen Klassen (Daten mit ComboBoxModel), aber jedenfalls Teil des Models, nicht der View


+


SlaterB hat gesagt.:


> ich hab das kürzlich mal gemacht und mir den coolen Begriff MetaModel ausgedacht, ein MetaModel hat mehrere normale Swing-Model als Listener, die wiederum ihre Views informieren



--------

außerdem habe ich eh schon auf eine Gelegenheit gewartet, einen kürzlich aufgeschnappten schlauen Satz zu zitieren:


> Vorsicht, Falle Nummer 1: MVC ist kein Schichtenmodell
> 
> Wir haben in der Praxis und in der Literatur schon häufiger eine Interpretation von MVC vorgefunden, die unserer Meinung nach einfach falsch ist.
> 
> MVC ist ein Muster für Interaktionen in der Präsentationsschicht. Es setzt damit bereits voraus, dass wir uns grundsätzlich auf eine Architektur eingelassen haben, die Schichten vorsieht und die Präsentation vom Rest der Anwendung trennt.


Galileo Computing :: Praxisbuch Objektorientierung – 8.2 Die Präsentationsschicht: Model, View, Controller (MVC)

MVC spielt sich (je nach Interpretation) nur innerhalb der Präsentation ab,
es ist ganz ok wenn alle Model und Listener auf Swing-Interfacen aufbauen, das Modell in MVC muss nicht auch die Datenbankschicht beinhalten

dass man mit nur einem Model in seinen Möglichkeiten begrenzt sein kann, ist davon unberührt, Stichwort MetaModel


----------



## Gast2 (27. Mrz 2009)

Kannst du ein kleines Beispiel von deinem MetaModel posten vielleicht kann iches mit dann vorstellen ...^^


----------



## Marco13 (27. Mrz 2009)

Ok, teilweise nähert sich das jetzt an. 

Die Benachrichtigungen über Änderungen hatte ich bei dem Dummy-Beispiel weggelassen, da es ja erstmal Read-Only war. In bezug auf das "Meta-Modell" (viele wissenschaftliche Veröffentlichungen bestehen bei genauerem Hinsehen nur daraus, dass ein Begriff für etwas altbekanntes definiert wird  : Ich finde es fragwürdig (d.h. nicht "nicht gut" oder "gut", sondern nur _fragwürdig_) ein (potentiell ZU spezielles) Swing-Model innerhalb seines eigenen Modelles zu verwenden, und das dann nach draußen zu exponieren. Dass ein Modell (ähnlich(!) wie bei einer Facade) auch aus mehreren Teilen bestehen kann, ist aber klar. 

Dass MVC ein Schichtenmodell ist wurde auch nicht angedeutet (auch wenn man bestimmte Aussagen vielleicht so interpretieren könnte). Aber ich finde, dass das Modell unabhängig von der View entstehen sollte - und das ""Wissen"", dass man irgendwelche Daten in irgendeiner bestimmten Swing-Component darstellen will, ist lange nicht so sicher, wie das Wissen darüber, was die Daten eigentlich SIND....

EDIT: Versuch einer Präzisierng - hab' gerade leider nicht viel Zeit für elaborierten code..


----------



## SlaterB (27. Mrz 2009)

hab doch gesagt, dass es etwa wie deins ist, aber bitte 
so wie ich es benötigte ein Model für zwei Tabellen, die unterschiedliche Anteile derselben Daten anzeigen,

ändert man in einer Tabelle den Vornamen, erscheint er auch in der anderen


```
public class TestGUI extends JFrame {

	public TestGUI() {

		PersonMetaModel metaModel = new PersonMetaModel();
		JTable tableWith = new JTable(new PersonTableModel(true, metaModel));
		JTable tableWithout = new JTable(new PersonTableModel(false, metaModel));

		add(tableWith, BorderLayout.NORTH);
		add(tableWithout, BorderLayout.SOUTH);
		setSize(400, 300);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);

	}

	public static void main(String[] args) {
		new TestGUI();
	}

}

class Person {
	String firstName;

	String lastName;

	public Person(String firstName, String lastName) {
		super();
		this.firstName = firstName;
		this.lastName = lastName;
	}

}

class PersonMetaModel {
	private List<ChangeListener> listener = new ArrayList<ChangeListener>();

	private List<Person> personList = new ArrayList<Person>();

	
	public PersonMetaModel() {
		this.personList.add(new Person("Karl","Ranseier"));
		this.personList.add(new Person("Boris","Becker"));
	}

	public Person get(int index) {
		return this.personList.get(index);
	}

	public int size() {
		return this.personList.size();
	}

	public void changed() {
		for (ChangeListener c : this.listener) {
			c.changed();
		}
	}

	public void addListener(ChangeListener listener) {
		this.listener.add(listener);
	}
}

interface ChangeListener {
	public void changed();
}

class PersonTableModel extends AbstractTableModel implements ChangeListener {

	private boolean showLastName = false;

	private PersonMetaModel metaModel;

	public PersonTableModel(boolean showLastName, PersonMetaModel metaModel) {
		this.showLastName = showLastName;
		this.metaModel = metaModel;
		this.metaModel.addListener(this);
	}

	public int getColumnCount() {
		return (this.showLastName ? 2 : 1);
	}

	public int getRowCount() {
		return this.metaModel.size();
	}

	public Object getValueAt(int rowIndex, int columnIndex) {
		Person p = this.metaModel.get(rowIndex);
		if (columnIndex == 0) {
			return p.firstName;
		} else {
			return p.lastName;
		}
	}

	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return true;
	}

	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		// ob das hier erlaubt ist oder eine andere Instanz das machen sollte,
		// sei außen vor, das funktioniert ja hier ganz ohne Listener
		Person p = this.metaModel.get(rowIndex);
		if (columnIndex == 0) {
			p.firstName = (String) aValue;
		} else {
			p.lastName = (String) aValue;
		}
		this.metaModel.changed();
	}

	public void changed() {
		fireTableDataChanged();
	}

}
```


----------



## Marco13 (27. Mrz 2009)

(So als Nachtrag: Mit sowas würde ich auch konform gehen - einige Aussagen vorher klangen für mich nach etwas ganz anderem, als das, was du gerade gepostet hast)


----------



## SlaterB (27. Mrz 2009)

ich fand Swing-Models früher (auch?) relativ speziell, aber im Laufe der Zeit immer weniger, 
im Grunde sind es beliebige Container, die nur size, get + vielleicht set anbieten und irgendeine Art von Listener unterstützen, welche auch nur ein Interface sind,

weniger kann man eigentlich nicht verlangen, irgendeine kleine Schnittstelle muss man den komplexen View-Komponenten wie JTable ja geben


----------



## Gast2 (27. Mrz 2009)

Marco13 hat gesagt.:


> (So als Nachtrag: Mit sowas würde ich auch konform gehen - einige Aussagen vorher klangen für mich nach etwas ganz anderem, als das, was du gerade gepostet hast)


Dito.

Ich hab einige Aussagen GANZ ANDERS interpretiert und verstanden ...


----------



## SlaterB (27. Mrz 2009)

dann war das Beispiel ja doch nützlich


----------



## Verjigorm (27. Mrz 2009)

Memo an mich selbst:
Poste keine "einfache" Frage(n) mehr über die sich eine halbe Community den Kopf zerbricht


----------



## Gast2 (27. Mrz 2009)

> dann war das Beispiel ja doch nützlich



Schon 



> Memo an mich selbst:
> Poste keine "einfache" Frage(n) mehr über die sich eine halbe Community den Kopf zerbricht



halbe community ist ein bischen übertrieben ... wäre mir aber lieb gewesen...
hätte mich interessiert wie das die anderen so handhaben bzw. sehen


----------



## Verjigorm (27. Mrz 2009)

Naja ist ja Freitag Mittag, da schaut vielelicht nicht mehr jeder hier rein 

In diesem Sinne:
Schönes Wochenende


----------



## mvitz (27. Mrz 2009)

Verjigorm hat gesagt.:


> Memo an mich selbst:
> Poste keine "einfache" Frage(n) mehr über die sich eine halbe Community den Kopf zerbricht



Naja, ich finde so Threads immer sehr interessant und aufschlussreich, auch wenn ich bei solchen Threads dann häufig nur mitlese, bin ich der Meinung das man gerade durch solche Threads auch lernen und eine andere Sicht auf spezielle Dinge bekommen kann.


----------



## André Uhres (27. Mrz 2009)

Marco13 hat gesagt.:


> Wenn das ganze dann mal in einer JList dargestellt werden soll, was soll man dann machen? Das ComboBoxModel in ein ListModel ändern? Eine Implementierung von ListModel anbieten, die an ein ComboBoxModel delegiert? Häm... ne, ich versteh' das gerade nicht ... :bahnhof:


Ja, ich versteh's auch nicht, warum Swing nicht einheitlich in den Models ist.


----------



## Marco13 (27. Mrz 2009)

Ehrlich gesagt war ich leicht  als ich gemerkt habe, dass ich mir für die Verdeutlichung dieses Punktes genau das besch****enste Beispiel rausgesucht hatte, das es gibt: ComboBoxModel erbt von ListModel...  Aber an der grundsätzlichen Problematik (wie etwa im anderen Beispiel: 2 ListModels vs. ein 2-spaltiges TableModel oder so) änder das ja nichts.


----------



## Ebenius (27. Mrz 2009)

Ist nicht ein Modell die Schnittstelle für die Daten einer Komponente? Sollte nicht das Modell die Daten so anbieten wie dies für die Komponente sinnvoll ist? Wäre nicht eine zweite Spalte in einer Liste äußerst verwunderlich? Hällt den Entwickler die Existenz zweier verschiedener *Interfaces* davon ab, eine Klasse Modell für zwei Komponentenarten zu sein?

Fragt sich der Ebenius.


----------



## Gast2 (27. Mrz 2009)

Ebenius hat gesagt.:


> Ist nicht ein Modell die Schnittstelle für die Daten einer Komponente? Sollte nicht das Modell die Daten so anbieten wie dies für die Komponente sinnvoll ist? Wäre nicht eine zweite Spalte in einer Liste äußerst verwunderlich? Hällt den Entwickler die Existenz zweier verschiedener *Interfaces* davon ab, eine Klasse Modell für zwei Komponentenarten zu sein?
> 
> Fragt sich der Ebenius.



Ja okay wir haben jetzt einfaches Beispiel, also ich finde es besser die Daten "neutral" zu halten und nicht von irgendwelchen Swing sonstige Komponente Sachen abhängig zu machen, weil so kann die Logik auch für eine SWT, Webanwendung usw. verwendet werden oder würdest du dann jedes mal dein Model anpassen oder neue Interface anbieten????
Also ich finde die View sollte die Daten neutral bekommen und dann darstellen

Gruß


----------



## André Uhres (27. Mrz 2009)

Ebenius hat gesagt.:


> ...Hällt den Entwickler die Existenz zweier verschiedener *Interfaces* davon ab, eine Klasse Modell für zwei Komponentenarten zu sein?...


Ein Entwickler kann eine Klasse Modell sein?? 
Das Problem oben war ja, daß die Daten verdoppelt wurden (durch den Kopiervorgang für die Combobox).


----------



## Ebenius (27. Mrz 2009)

Ohje muss ich getrunken haben.  Aber was ich meinte ist klar. Ich kann doch eine Klasse haben, die sowohl das ListModel als auch das TableModel-Interface implementiert und die selben Daten für zwei verschiedene Komponenten modelliert.

Ebenius


----------



## André Uhres (27. Mrz 2009)

Ebenius hat gesagt.:


> Ich kann doch eine Klasse haben, die sowohl das ListModel als auch das TableModel-Interface implementiert und die selben Daten für zwei verschiedene Komponenten modelliert.


Sicher kann man das machen, aber wozu so ein Aufwand für unser simples Beispiel??
Mein Vorschlag oben hat einfach zum Ziel, den Kopiervorgang einzusparen, der imho auch in diesem einfachen Beispiel sinnlos ist. Ob der Rückgabewert DefaultComboBoxModel, ComboBoxModel oder ListModel heißt, ist dabei wohl von untergeordneter Bedeutung. Allgemein wird aber ein Programm flexibler sein, wenn wir ein passendes Interface benutzen, um auf ein Objekt zuzugreifen (respektiv die oberste Klasse in der Hierarchie, die die gewünschte Funkionalität hat).


----------



## Wildcard (28. Mrz 2009)

SirWayne, modellier dir einfach mal ein Model mit EMF, dann siehst du wie so etwas idealerweise aussehen sollte.


----------



## Gast2 (30. Mrz 2009)

ja wollte ich schon lang mal machen, dachte aber dass man für so ein simples Beispiel auch so eine gute/sinvolle Erklärung bekommen kann, wie es am besten gemacht werden sollte


----------



## Gast2 (1. Apr 2009)

Ah was ich noch sagen/fragen wollte ich denk mal nicht jeder hat sich mit EMF seine Models generieren lassen oder schon mal gemacht, von daher muss ja auch jeder Erfahrungen darüber berichten können wie er/sie sowas angeht bzw. sieht ...


Noch ne Frage: wo benachrichtigt ihr die listeners/views, dass sich das model geändert hat?

im controller? oder im model??? ...


----------



## Ebenius (1. Apr 2009)

Das Modell gibt dem Controller Bescheid, wenn es sich (und in welcher Weise es sich) verändert hat. Views sind passiv. Sie reagieren nicht automatisch auf Veränderungen sondern nur auf Befehl (des Controllers). Der Controller entscheidet (zum Beispiel anhand eines / mehrerer Events des Modells / der Modelle) wann er welche View(s) aktualisieren möchte.

Ebenius


----------



## Stefan S. (1. Apr 2009)

Ebenius hat gesagt.:


> Das Modell gibt dem Controller Bescheid, wenn es sich (und in welcher Weise es sich) verändert hat. Views sind passiv. Sie reagieren nicht automatisch auf Veränderungen sondern nur auf Befehl (des Controllers). Der Controller entscheidet (zum Beispiel anhand eines / mehrerer Events des Modells / der Modelle) wann er welche View(s) aktualisieren möchte.



Das ist nicht richtig. Views implementieren das Observer Muster und reagieren auf Veränderungen des Models dynamisch.

Der Controller ist eine reine Zwischenschicht, zwischen View und Model. Das Model hat intern keine "Ahnung" vom View. Es stellt nach außen nur ein Interface bereit, so dass sich Beobachter beim Model registrieren können und damit der Controller zugreifen kann.

Der Controller ist zuständig für die Steuerung. Er nimmt die Benutzereingaben der View entgegen und führt entsprechende Operationen am Model aus.

Das Model enthält auch die Anwendungslogik für die Datenverarbeitung. Besonders klar wird es bei einer Datenbankanwendung. Das Model stellt den Zugriff bereit.

Wenn man eine GUI bastelt, sollte man die Listener in der View halten. Wird ein Button gedrückt, ruft man aus dem Listener den Controller auf, der dann entscheidet was das Drücken dieses Button für Konsequenzen für das Model und die View hat.


----------



## André Uhres (1. Apr 2009)

Ich habe eine Frage: sollten wir mit dem Einsatz von Modelevents nicht vorsichtig sein? Sollten die Events nicht möglichst nur von der View ausgehen? Jedenfalls scheint's mir gefährlich zu werden, wenn von zwei Seiten geschossen wird, oder wie seht ihr das?


----------



## Ebenius (1. Apr 2009)

Stefan S. hat gesagt.:


> Das ist nicht richtig. Views implementieren das Observer Muster und reagieren auf Veränderungen des Models dynamisch.


 Ohje, stimmt. Was ich beschrieben hab kommt schon eher aus der Model-View-Adapter-Architektur (wenn man "Controller" durch "Adapter" austauscht). Oder bin ich dabei noch immer auf dem Holzweg?

Ebenius


----------



## Marco13 (1. Apr 2009)

Hm - man unterscheidet da wohl grundsätzlich zwischen einem "Active Model" und eine "Passive Model". 

Das passive wird NUR vom Controller geändert, und der weiß dann auch, dass er danach der View bescheid sagen muss, sie möge sich bitte updaten.

Das aktive Model wirft selbst die Events, und die View ist als Listener/Observer angehängt.

In welcher Hinsicht soll es "gefährlich" werden, wenn beide Seiten Events werfen? (Abgesehen vom potentiellen Problem, dass Model und View sich gegenseitig in einem Endlos-Pingpong Events zuschachern - dass muss man vermeiden, indem man wirklich NUR Events wirft, wenn sich wirklich etwas geändert hat)


----------



## Stefan S. (1. Apr 2009)

André Uhres hat gesagt.:


> Ich habe eine Frage: sollten wir mit dem Einsatz von Modelevents nicht vorsichtig sein? Sollten die Events nicht möglichst nur von der View ausgehen? Jedenfalls scheint's mir gefährlich zu werden, wenn von zwei Seiten geschossen wird, oder wie seht ihr das?



Das Model sollte überhaupt nicht auf Userereignisse reagieren. Zitat:



> Is the domain-specific representation of the information on which the application operates. Domain logic adds meaning to raw data (for example, calculating whether today is the user's birthday, or the totals, taxes, and shipping charges for shopping cart items).Many applications use a persistent storage mechanism (such as a database) to store data. MVC does not specifically mention the data access layer because it is understood to be underneath or encapsulated by the model.Model?view?controller - Wikipedia, the free encyclopedia



Das Modell stellt nur die Anwendungslogik für die Datenschicht bereit!



Ebenius hat gesagt.:


> Ohje, stimmt. Was ich beschrieben hab kommt schon eher aus der Model-View-Adapter-Architektur (wenn man "Controller" durch "Adapter" austauscht). Oder bin ich dabei noch immer auf dem Holzweg?



Fast. Das MVA Muster grenzt die View noch stärker vom Model ab. Es ist prinzipiell ein von MVC abgeleitetes Muster, bei dem die Schranken etwas stärker definiert sind.


----------



## Ebenius (1. Apr 2009)

Stefan S. hat gesagt.:


> Fast. Das MVA Muster grenzt die View noch stärker vom Model ab. Es ist prinzipiell ein von MVC abgeleitetes Muster, bei dem die Schranken etwas stärker definiert sind.


Du meinst: Die View darf dazu auch keine Daten vom Modell holen, sondern bekommt sie vom Adapter mitgeteilt. Den Teil hatte ich eigentlich gar nicht explizit erwähnt. Oder meinst Du noch einen anderen Punkt?

Ebenius


----------



## Stefan S. (1. Apr 2009)

Ebenius hat gesagt.:


> Du meinst: Die View darf dazu auch keine Daten vom Modell holen, sondern bekommt sie vom Adapter mitgeteilt.



Bingo!

Beim normalen MVC ist es durchaus nicht unüblich das die View das Model nach dessen Status abfragt. Es sollte zwar niemals Daten im Modell ändern, aber es darf durchaus den Zustand abfragen. Das ist beim MVA etwas strenger geregelt. Dort ruft es das Model überhaupt nicht auf.

Eigentlich ist das reine zusammengesetzte MVC-Muster elegant, solange man gegen ein Interface programmiert.

Zu Entwurfsmustern empfehle ich das Standardwerk der Gang of Four.


----------



## Wildcard (1. Apr 2009)

Stefan S. hat gesagt.:


> Eigentlich ist das reine MVC Entwurfsmuster optimal, solange man gegen ein Interface programmiert.
> 
> Zu Entwurfsmustern empfehle ich das Standardwerk der Gang of Four.


Nur ist MVC kein Entwurfsmuster, sondern ein Architekturmuster


----------



## Ebenius (1. Apr 2009)

Stefan S. hat gesagt.:


> Zu Entwurfsmustern empfehle ich das Standardwerk der Gang of Four.


-Entwurfs+Architektur 

Derzeit hält mich leider Benjamin von Stuckrad-Barres Livealbum sehr aktiv davon ab. 

Ebenius


----------



## Gast2 (1. Apr 2009)

okay das war mir jetzt ein bischen viel (vielleicht morgen nochmal lesen)...
Wenn Ihr euch alle versteht^^ könnte das mal jemand an einem Beispiel kurz nochmal erklären??????:L


----------



## Wildcard (1. Apr 2009)

Ebenius hat gesagt.:


> Derzeit hält mich leider Benjamin von Stuckrad-Barres Livealbum sehr aktiv davon ab.


Mach dir nichts draus, das Buch behandelt sowieso keine Architekturmuster. Es sagt lediglich: MVC ist kein Entwurfsmuster bei der allgemeinen Erklärung was denn nun ein Entwurfsmuster sei :bae:


----------



## Stefan S. (1. Apr 2009)

Wildcard hat gesagt.:


> Nur ist MVC kein Entwurfsmuster, sondern ein Architekturmuster



Das ist richtig. Das MVC setzt sich aus 3 elementaren Entwurfsmustern zusammen, Observer, Strategy und Composite. Ich bezeichne es meist als zusammengesetztes Entwurfsmuster.


----------



## Wildcard (1. Apr 2009)

Stefan S. hat gesagt.:


> Eigentlich ist das reine MVC Entwurfsmuster optimal, solange man gegen ein Interface programmiert.


Wie kommst du darauf das es 'optimal' sei? MVC ist weder das einzig richtige, noch das flexibelste und ausserdem ist es recht schwierig die Trennung sauber aufrecht zu erhalten.
MVA hat zB durchaus schlagkräftige Argumente, ebenso wie naked objects.
Heißt ja nun nicht das solche Ansätze grundsätzlich zu bevorzugen wären, aber 'optimal' ist schon eine bestenfalls zweifelhafte Aussage.


----------



## Stefan S. (1. Apr 2009)

SirWayne hat gesagt.:


> okay das war mir jetzt ein bischen viel (vielleicht morgen nochmal lesen)...
> Wenn Ihr euch alle versteht^^ könnte das mal jemand an einem Beispiel kurz nochmal erklären???





SirWayne hat gesagt.:


> Noch ne Frage: wo benachrichtigt ihr die listeners/views, dass sich das model geändert hat?
> 
> im controller? oder im model??? ...



Informiere dich über Java *Observable* und *Observer*. Das Model erweitert die Klasse Observable, die View implementiert das Interface Observer. Beim Start registriert sich die View beim Model. Ändern sich Daten im Model, werden alle Observer mithilfe von setChanged() und notifyObservers() benachrichtigt.


----------



## Stefan S. (1. Apr 2009)

Wildcard hat gesagt.:


> Wie kommst du darauf das es 'optimal' sei? MVC ist weder das einzig richtige, noch das flexibelste



Ich sagte nicht dass das MVC Muster das Beste Muster sei, ich sagte das es im Vergleich zum MVA meiner Ansicht nach optimal sei, sofern man einige Richtlinien beachtet.



Wildcard hat gesagt.:


> und ausserdem ist es recht schwierig die Trennung sauber aufrecht zu erhalten.



Ansichtssache.



Wildcard hat gesagt.:


> Heißt ja nun nicht das solche Ansätze grundsätzlich zu bevorzugen wären, aber 'optimal' ist schon eine bestenfalls zweifelhafte Aussage.



Jetzt wollen wir hier aber nicht den Korinthenkacker spielen, oder?

EDIT: Ich habe das absolute Adjektiv nun ausgetauscht. Das dürfte dich hoffentlich zufrieden stellen.


----------



## Wildcard (1. Apr 2009)

Weniger absolute Aussagen finde ich in diesem Zusammenhang treffender, richtig, aber davon abgesehen interessiert es mich schon. Warum ist für dich MVC zB besser als MVA?
Ich muss mir nur Swing MVC ansehen und bin schon genervt von den ListModels, TableModels, ComboCellModels, TreeModels,...
Den Adapter Ansatz finde ich da persönlich ansprechender.


----------



## Stefan S. (1. Apr 2009)

Wildcard hat gesagt.:


> Weniger absolute Aussagen finde ich in diesem Zusammenhang treffender, richtig,



Ich bin auch kein Fan von absoluten Aussagen. Insbesondere wenn Begriffe, wie immer oder nie fallen. Machmal fallen sie aber im Eifer des Gefechts trotzdem. 



Wildcard hat gesagt.:


> aber davon abgesehen interessiert es mich schon. Warum ist für dich MVC zB besser als MVA?



Das MVC ist meiner Ansicht nach etwas flexibler und dennoch sauber programmierbar, sofern man sich an einige Richtlinien hält. Letztlich ist es aber eine Frage der Anforderungen.



Wildcard hat gesagt.:


> Ich muss mir nur Swing MVC ansehen und bin schon genervt von den ListModels, TableModels, ComboCellModels, TreeModels,...
> Den Adapter Ansatz finde ich da persönlich ansprechender.



Das ist natürlich subjektiv zu bewerten und von Programmierer zu Programmierer unterschiedlich.


----------



## Wildcard (1. Apr 2009)

Stefan S. hat gesagt.:


> Das MVC ist meiner Ansicht nach etwas flexibler und dennoch sauber programmierbar, sofern man sich an einige Richtlinien hält. Letztlich ist es aber eine Frage der Anforderungen.


Das musst du jetzt aber schon erläutern, denn es gibt nur deshalb MVA, weil MVC nicht flexibel genug war (View and Modell gekoppelt).


----------



## Stefan S. (2. Apr 2009)

Wildcard hat gesagt.:


> Das musst du jetzt aber schon erläutern, denn es gibt nur deshalb MVA, weil MVC nicht flexibel genug war (View and Modell gekoppelt).



Die Frage ist nun was du unter flexibel verstehst. Wenn du damit meinst das MVA den Vorteil bietet das die View sauber getrennt ist und Model sowie View sehr einfach austauschbar, dann hast du recht. 

Ich verstehe unter Flexibilität allerdings den Vorteil von MVC in einer 2-Stufen Hierarchie arbeiten zu können, ohne die Komplexität zu steigern. Beim MVA benötigst du zusätzliche Mechanismen, wie Datenbindung und Auto-Updating um das zu erreichen.


----------



## Wildcard (2. Apr 2009)

Aber Databinding führt doch keine zusätzliche Komplexität ein, sondern vereinfacht die Sache ganz erheblich. Es ist wesentlich weniger Code notwendig, der Code ist robust, die Teile sauber getrennt und besser austauschbar.
Das lässt sich natürlich auch mit MVC erreichen (bis auch die Sache das View an Model gekoppelt ist), aber bei MVC brauchst du dann einen sehr erfahrenen Entwickler, bei MVA reicht ein weniger erfahrener.


----------



## André Uhres (2. Apr 2009)

Stefan S. hat gesagt.:


> Das Model sollte überhaupt nicht auf Userereignisse reagieren.


Aber der Controller reagiert ja auf Userereignisse und ändert dann das Model, nicht wahr? Wenn jetzt der Controller auch noch die Views ändert, bräuchte man ja gar keine Modelereignisse, oder? Der Controller (also nicht das Model) ist in dem Fall der Observable, wie es in unseren FAQ auch gezeigt wird.


----------



## Ebenius (2. Apr 2009)

Wildcard hat gesagt.:


> Ich muss mir nur Swing MVC ansehen und bin schon genervt von den ListModels, TableModels, ComboCellModels, TreeModels,...


ComboCellModels... 

Genau dieses Konzept gefällt mir an Swing unheimlich. Den direkten Vergleich zu SWT kann ich leider nicht ziehen. Mich dort soweit einzuarbeiten, dass ich dafür ein Gefühl bekomme, macht mir etwas zu viel Mühe.

Ebenius


----------



## Gast2 (2. Apr 2009)

Könnte einer mal MVC und MVA gegenüber stellen, damit man mal den unterschied sieht?

Okay nochmal paar Fragen:
Wenn alle Views sich beim Model registrieren...Und das Model alle Views benachrichtigt
für was braucht man dann noch den Controller??? Eine View kann ja dann direkt das Model ändern????
Hat die View dann eine Instanz vom Model?

ich hab das bis jetzt so verstanden, dass die views sich beim controller registrieren, die controller das model ändern und der controller alle views benachrichtigt(so wie in meinem anfangs bsp)... Ach ja  mein Besipiel ist ja so ähnlich wie in der FAQ...

Finde schade dass ihr das Thema so theoretisch behandelt...
Kommen genau die gleichen Fragen auf wie wenn man es in irgendwo etc. nachliest...


----------



## Stefan S. (2. Apr 2009)

Wildcard hat gesagt.:


> aber bei MVC brauchst du dann einen sehr erfahrenen Entwickler, bei MVA reicht ein weniger erfahrener.



Richtig. Ich bin allerdings kein Fan von aufgeblasenen Mustern, die das Abstraktionsniveau auf ein zu hohes Level heben.



André Uhres hat gesagt.:


> Aber der Controller reagiert ja auf Userereignisse und ändert dann das Model, nicht wahr? Wenn jetzt der Controller auch noch die Views ändert, bräuchte man ja gar keine Modelereignisse, oder? Der Controller (also nicht das Model) ist in dem Fall der Observable, wie es in unseren FAQ auch gezeigt wird.



Was sind Modelereignisse? Die View ist lediglich die Ansicht des Benutzers auf das Model.



SirWayne hat gesagt.:


> Okay nochmal paar Fragen:
> Wenn alle Views sich beim Model registrieren...Und das Model alle Views benachrichtigt
> für was braucht man dann noch den Controller??? Eine View kann ja dann direkt das Model ändern????
> Hat die View dann eine Instanz vom Model?
> ...



Wer behandelt das Thema theoretisch? 

Die View hat eine Instanz vom Model, primär natürlich um sich mit addObserver() beim Model als Beobachter einzutragen.

Der Controller übernimmt die Steuerung der Benutzereingaben. Ich drücke den Button on(), die View ruft daraufhin controller.on() auf. Dieser implementiert nun die Steuerungslogik, d.h. er bestimmt nun, was zu tun ist. Das kann zum Beispiel den Aufruf des Models beinhalten, mit dem Daten initialisiert werden und die Abschaltung des On-Buttuns (setEnabled( false) ) in der View.

Siehe

http://students.cs.byu.edu/~cs340ta/winter2009/hw/homeworks/Homework-05-MVC.pdf

Schau dir einmal größere Beispielapplikationen, wie Joomla 1.5 an. Dort wurde das MVC sehr schön umgesetzt.


----------



## mvitz (2. Apr 2009)

Stefan S. hat gesagt.:


> ...
> Was sind Modelereignisse?
> ...



Er meint damit vermutlich, dass das Model die View dann nicht mehr per Observer benachrichtigen muss, da dass ja dann auch durch den Controller geschehen kann.


Stefan S. hat gesagt.:


> ...
> Der Controller übernimmt die Steuerung der Benutzereingaben. Ich drücke den Button on(), die View ruft daraufhin controller.on() auf. Dieser implementiert nun die Steuerungslogik, d.h. er bestimmt nun, was zu tun ist. Das kann zum Beispiel den Aufruf des Models beinhalten, mit dem Daten initialisiert werden und die Abschaltung des On-Buttuns (setEnabled( false) ) in der View.


Hier kriege ich z.B. unter Swing immer wieder meine Probleme, wenn ich mehrere Panels habe, die alle denselben Controller verwenden sollen um z.B. ein Panel zur Dateieingabe und ein anderes zur Datenausgabe zu haben (vermutlich ist es ganz einfach, aber ich habe noch keinen Weg gefunden, der mir irgendwie 100% zusagt.



Stefan S. hat gesagt.:


> ...
> Schau dir einmal größere Beispielapplikationen, wie Joomla 1.5 an. Dort wurde das MVC sehr schön umgesetzt.
> ...


Da muss man finde ich nochmal stark unterscheiden. Joomla 1.5 ist eine Webapplikation. Meiner Meinung nach, ist es in einer Webapplikation wesentlich leichter MVC zu trennen, als in einer SwingApplikation, da du ja immer mit Response arbeitest und nicht wie in Swing nur einen Teil neu laden musst.


----------



## Wildcard (2. Apr 2009)

Ebenius hat gesagt.:


> Genau dieses Konzept gefällt mir an Swing unheimlich. Den direkten Vergleich zu SWT kann ich leider nicht ziehen. Mich dort soweit einzuarbeiten, dass ich dafür ein Gefühl bekomme, macht mir etwas zu viel Mühe.


Üblicherweise sieht das so aus:
[HIGHLIGHT="Java"]TreeViewer viewer = new TreeViewer(parent);
viewer.setContentProvider(aTreeContentProvider);
viewer.setLabelProvider(aLabelProvider);
viewer.setInput((Object)myModel);[/HIGHLIGHT]

Model ist völlig beliebig, Object.
Der ContentProvider übersetzt das Model für den Viewer (der Adapter).
Der LabelProvider stellt labels und Icons bereit.

typischer contentprovider:

[HIGHLIGHT="Java"]Object[] getChildren(Object parent){
   return ((MyDomainModelContainer)parent).getFooChildren().toArray();
}[/HIGHLIGHT]


typischer LabelProvider:

[HIGHLIGHT="Java"]String getText(Object o){
   return ((MyDomainModel)o).getName();
}

ImageDescriptor getIcon(Object o){
   if(o instanceof MyDomainModelFoo){
       return ImageRegistry.getImage("foo");
  }
}[/HIGHLIGHT]

Sehr wenig Code, wiederverwendbare Label und ContentProvider, View und Model entkoppelt. 
Idealerweise koppelt man das nun für die Benutzerinteraktion mit JFace Databinding.


----------



## Gast2 (2. Apr 2009)

Stefan S. hat gesagt.:


> Richtig. Ich bin allerdings kein Fan von aufgeblasenen Mustern, die das Abstraktionsniveau auf ein zu hohes Level heben.
> 
> 
> 
> ...



was spricht dagegen die views beim controller zu registrieren ???? 
was spricht dagegen dass der controller die views benachrichtigt???



			
				Wildcard hat gesagt.:
			
		

> Sehr wenig Code, wiederverwendbare Label und ContentProvider, View und Model entkoppelt.


Aber nur für das gleiche Model wiederverwendbar sonst müsstest ja alles mit instanceOf unterscheiden...


----------



## Wildcard (2. Apr 2009)

SirWayne hat gesagt.:


> Aber nur für das gleiche Model wiederverwendbar sonst müsstest ja alles mit instanceOf unterscheiden...


Zum einen ist so ein ContentProvider sehr schlank, zum anderen ist es sinn des ganzen ihn für genau ein Model zu erstellen. Diesen ContentProvider kannst du dann aber für viele verschiedene Views auf das gleiche Model verwenden.
In EMF wird zB in einer AdapterFactory ein 'universal' ContentProvider erzeugt der für Listen, Tabellen, Bäume,... passt.


----------



## Stefan S. (2. Apr 2009)

SirWayne hat gesagt.:


> was spricht dagegen die views beim controller zu registrieren ????



Weil das kein MVC mehr ist, das ist eine eigenwillige Interpretation. Wozu sollten sich die Views beim Controller registrieren, der Controller übersetzt nur Benutzersteuerungen.



SirWayne hat gesagt.:


> was spricht dagegen dass der controller die views benachrichtigt???



Er banachrichtigt doch die Views, falls das notwendig ist.

Ich habe auch keine Lust hier zehnmal dasselbe zu schreiben. Ich habe dir einen expliziten Link oben gegeben, samt Lektüre. Hier ist noch ein guter, den ich gerade mit Google auf die Schnelle gefunden habe:

model/view/controller

Und hier das offizielle Java Buch "Head First Design Patterns ".

Head First Design Patterns | O'Reilly Media







Da steht alles was es über MVC zu wissen gibt, samt Codebeispielen. Die gibts dort kostenlos zum runterladen.

Die Torte quasi mit Zuckerguß oben drauf. Ende der Durchsage! ;(


----------



## Gast2 (3. Apr 2009)

Stefan S. hat gesagt.:


> Weil das kein MVC mehr ist, das ist eine eigenwillige Interpretation. Wozu sollten sich die Views beim Controller registrieren, der Controller übersetzt nur Benutzersteuerungen.
> 
> 
> 
> ...



Ich weiß langsam was du meinst ich habs mir jetzt 100 mal durchgelesen...
Du solltest mehr auf die Frage eingehen und nicht 100000 mal das gleiche runterlabern davon hat kein Mensch was gesagt.
1. Ist es nicht nur meine Interprtation http://www.java-forum.org/51799-post11.html
hier ist es genau so gemacht dass der controller die views registriert...
2. Ich hab verstanden, dass es (meistens) so gemacht wird, aber ich hab gefragt was dagegen spricht, die views beim controller aufzunehmen und eine antwort es ist kein MVC ist ein schlechtes Argument(find ich), ein Argument mit einem richtigen Nachrteil würde mich mehr Überzeugen...

@Wildcard
Hat mich überzeugt klingt einleuchtend


----------



## André Uhres (3. Apr 2009)

Stefan S. hat gesagt.:


> Weil das kein MVC mehr ist, das ist eine eigenwillige Interpretation. Wozu sollten sich die Views beim Controller registrieren, der Controller übersetzt nur Benutzersteuerungen.


Sollten unsere Mods und User wirklich alle so doof sein, daß sie einen gravierenden Fehler über vier Jahre lang nicht bemerkt hätten? In den FAQ wird MVC so erklärt:

```
public class WindController extends Observable implements WindControllable {
    private Wind wind;

    public WindController() {
        WindViewer viewer = new WindViewer( this );
        addObserver( viewer );
        wind = new Wind();
    }
```


----------



## maki (3. Apr 2009)

Für MVC und andere GUI Patterns hat Martin Fowler auch sehr gute Artikel: 

GUI Architectures
Martin Fowler: eaaDev (unter "Presentation Patterns")


----------



## Stefan S. (3. Apr 2009)

SirWayne hat gesagt.:


> Ich weiß langsam was du meinst ich habs mir jetzt 100 mal durchgelesen...
> Du solltest mehr auf die Frage eingehen und nicht 100000 mal das gleiche runterlabern davon hat kein Mensch was gesagt.
> 1. Ist es nicht nur meine Interprtation http://www.java-forum.org/51799-post11.html
> hier ist es genau so gemacht dass der controller die views registriert...



Ja genau. Du und die FAQ gegen den Rest der Welt. 

Mach nur so weiter, mir ist das vollkommen egal.



SirWayne hat gesagt.:


> 2. Ich hab verstanden, dass es (meistens) so gemacht wird, aber ich hab gefragt was dagegen spricht, die views beim controller aufzunehmen und eine antwort es ist kein MVC ist ein schlechtes Argument(find ich), ein Argument mit einem richtigen Nachrteil würde mich mehr Überzeugen...



Ich habe dir bereits 10x erklärt warum das Model und nicht der Controller Observable erweitert. Falls du das noch immer nicht kappiert hast, ist es nicht mein Problem. Ich habe es auch nicht nötig, mich von dir für meine Hilfe beleidigen zu lassen nur weil du offensichtlich zu faul bist, dich durch die geposteten Links zu lesen. Deshalb landest du jetzt auf _ignore_.


----------



## Ebenius (3. Apr 2009)

Stefan S., eine Beleidigung kann ich nirgends finden.

André, meiner Meinung nach ist entweder der FAQ-Beitrag falsch, oder der Wikipedia Beitrag über MVC. Eines der beiden sollte geändert werden.



			
				FAQ hat gesagt.:
			
		

> *Controll - Ebene:*
> Die Klassen regeln die Kommunikation zwischen den Model und View. Sie dienen dazu Änderungen in den Model Klassen den View Klassen mitzuteilen bzw. vice versa.



vs.


			
				Wikipedia-Artikel hat gesagt.:
			
		

> *Modell (model)*
> Das Modell enthält die darzustellenden Daten und gegebenenfalls (abhängig von der Implementation des MVC-Patterns) auch die Geschäftslogik. Es ist von Präsentation und Steuerung unabhängig. Die Bekanntgabe von Änderungen an relevanten Daten im Modell geschieht nach dem Entwurfsmuster „Beobachter“.



Ebenius


----------



## maki (3. Apr 2009)

Denke man sollte MVC nicht überbewerten, zB. als echtes Muster 
Ist mehr so etwas wie ein Konzept als ein Muster.
Selbst bei "echten" Mustern gibt es immer mehrere Wege der Implementierung.

Die "reinrassige" Implementierung ist in Smalltalk und hat sich seit dem öfters geändert.


----------



## Ebenius (3. Apr 2009)

maki hat gesagt.:


> Denke man sollte MVC nicht überbewerten


Das sehe ich in der Realität ähnlich. Wenn wir aber einen FAQ-Beitrag haben, der sich zur Aufgabe gemacht hat, das MVC-Muster zu erklären, dann sollte er dies wenigstens nicht falsch tun.

Ebenius


----------



## Stefan S. (3. Apr 2009)

André Uhres hat gesagt.:


> Sollten unsere Mods und User wirklich alle so doof sein, daß sie einen gravierenden Fehler über vier Jahre lang nicht bemerkt hätten? In den FAQ wird MVC so erklärt:
> 
> ```
> public class WindController extends Observable implements WindControllable {
> ...



Ganz offensichtlich wurde dieser Fehler bisher nicht bemerkt oder die meisten User haben ihn schlicht übersehen. 

Die View ist die Sicht des Nutzers auf das Model, welches die vollständige Anwendungslogik der Daten enthält. Das Model kann seinen Zustand intern verändern, z.B. wenn ein Musikstück abgespielt wird. Darüber werden dann die Observer benachrichtigt. Es sollte recht deutlich zum Vorschein kommen das der Controller nicht der Observable sein kann, er ist schließlich nur die Steuerungskomponente der View, mit dem das Model und die View selbst ggf. beeinflusst werden. 

Wenn beispielsweise das Model eine Uhr intern repräsentiert, die die Sekunden intern hochzählt, wie soll dann der Controller die View darüber benachrichtigen? Er bekommt doch von der Zustandsänderung der Daten überhaupt nichts mit.

Deshalb heißt es auch bei Wikipedia.



> Das Modell enthält die darzustellenden Daten und gegebenenfalls (abhängig von der Implementation des MVC-Patterns) auch die Geschäftslogik. Es ist von Präsentation und Steuerung unabhängig. Die Bekanntgabe von Änderungen an relevanten Daten im Modell geschieht nach dem Entwurfsmuster „Beobachter“.


Dasselbe sagt:

Class::MVC - model-view-controller paradigma - search.cpan.org
model/view/controller
Head First Design Patterns | O'Reilly Media
MVC: Model-View-Controller Design Pattern used in Struts, Ruby on Rails, etc
JavaTech: an introduction to ... - Google Book Search
http://harbormist.com/jett/pat/mvc.ppt
http://csdl.ics.hawaii.edu/~johnson/413f06/18.JavaGUI.pdf
:: christianroessler.net - forum / Model View Controller (MVC) - Konzept mit JAVA
http://www.sws.bfh.ch/~amrhein/Skripten/Swing/Pattern.pdf

und alle anderen Quellen, die es im Internet gibt.

Selbst im Buch der Go4 wird das so erklärt. Also entweder liegen hier selbst die Experten falsch oder die FAQ hier ist nicht korrekt. Sucht euch das Plausibelste aus.


----------



## Stefan S. (3. Apr 2009)

Ebenius hat gesagt.:


> Stefan S., eine Beleidigung kann ich nirgends finden.



Ich schon. Ich zitiere:



SirWayne hat gesagt.:


> Du solltest mehr auf die Frage eingehen und nicht 100000 mal das gleiche *runterlabern* davon hat kein Mensch was gesagt.



Beleidigungen werden immer subjektiv empfunden. Daher ist es mein gutes Recht diesen User auf meine Ignoreliste zu setzen.


----------



## maki (3. Apr 2009)

> Das Modell enthält die darzustellenden Daten und gegebenenfalls (abhängig von der Implementation des MVC-Patterns) auch die Geschäftslogik. Es ist von Präsentation und Steuerung unabhängig. Die Bekanntgabe von Änderungen an relevanten Daten im Modell geschieht nach dem Entwurfsmuster „Beobachter“.
> ...
> Dasselbe sagt:
> ..
> MVC: Model-View-Controller Design Pattern used in Struts, Ruby on Rails, etc


Das will ich sehen, wie struts per Beobachter Änderungen im Modell feststellt und daraufhin die View aktualisiert 

Mal ernsthaft, eine wichtige Sache die mir bis jetzt in der Diskussion über MVC fehlt ist die Tatsache das es sich beim C in MVC, also dem Controller, um einen Frontcontroller handelt, nicht um einen Application-/BusinessController.



Ebenius hat gesagt.:


> Das sehe ich in der Realität ähnlich. Wenn wir aber einen FAQ-Beitrag haben, der sich zur Aufgabe gemacht hat, das MVC-Muster zu erklären, dann sollte er dies wenigstens nicht falsch tun.


Das ist veständlich Ebenius und dem will ich auch gar nicht widersprechen.
Dachte nur das wir uns die "Beleidigungen" (sofern es denn wirklich welche gegeben haben sollte) für den nächsten SIngleton Thread aufheben sollten *g*


----------



## Stefan S. (3. Apr 2009)

maki hat gesagt.:


> Dachte nur das wir uns die "Beleidigungen" (sofern es denn wirklich welche gegeben haben sollte) für den nächsten SIngleton Thread aufheben sollten *g*



Gibt es etwa Meinungsunterschiede zum double-checked locking? Mit _volatile_ müsste das Problem doch beseitigt sein.


----------



## maki (3. Apr 2009)

Stefan S. hat gesagt.:


> Gibt es etwa Meinungsunterschiede zum double-checked locking? Mit _volatile_ müsste das Problem doch beseitigt sein.


Nee, 

eher pro vs. contra Singletons, Anti-Pattern oder nicht, gutes Design oder nicht, testbarkeit, wie schlimm ist ein einziges Singleton in der App, etc. pp.


----------



## Stefan S. (3. Apr 2009)

maki hat gesagt.:


> Nee,
> 
> eher pro vs. contra Singletons, Anti-Pattern oder nicht, gutes Design oder nicht, testbarkeit, wie schlimm ist ein einziges Singleton in der App, etc. pp.



Achso. Dann macht der Verweis auf "Beleidigungen" natürlich Sinn.


----------



## Marco13 (3. Apr 2009)

Dass der FAQ-Beitrag nicht meiner Interpretation von MVC entspricht, war mir auch mal aufgefallen. Aber wie hier auch schon (und auch schon gaaanz am Anfang) erwähnt wurde: Man hat glaube ich bestimmte Freiheiten. Es macht zwar IMHO keinen Sinn, den Controller Observable zu machen, aber ich denke gerade die Frage, was der Controller ist, hatte ich ja schon anfangs aufgeworfen, und viel mehr als "Hier ist das so", "Ich denke, dass ist so", "Ich habe mal gelesen, dass...", und "Wenn das-und-das so-und-so ist..." kam bisher in diesem Thread für mich nicht rüber. Das Model sollte die View nicht direkt kennen. Viel mehr bleibt (für mich, natürlich, wieder ganz subjektiv  ) von MVC damit nicht übrig.


----------



## Stefan S. (3. Apr 2009)

Marco13 hat gesagt.:


> Dass der FAQ-Beitrag nicht meiner Interpretation von MVC entspricht, war mir auch mal aufgefallen. Aber wie hier auch schon (und auch schon gaaanz am Anfang) erwähnt wurde: Man hat glaube ich bestimmte Freiheiten. Es macht zwar IMHO keinen Sinn, den Controller Observable zu machen, aber ich denke gerade die Frage, was der Controller ist, hatte ich ja schon anfangs aufgeworfen, und viel mehr als "Hier ist das so", "Ich denke, dass ist so", "Ich habe mal gelesen, dass...", und "Wenn das-und-das so-und-so ist..." kam bisher in diesem Thread für mich nicht rüber. Das Model sollte die View nicht direkt kennen. Viel mehr bleibt (für mich, natürlich, wieder ganz subjektiv  ) von MVC damit nicht übrig.



Es gibt bekannterweise unterschiedliche Interpretationen des MVC Musters. Eines steht aber fest, der Controller ist nie der Observable! Den Grund hatte ich bereits oben ausführlich beschrieben.

Der Controller kann aber in einigen Designs auch zum Observer werden, z.B. um bei Änderungen der Daten direkt die View zu manipulieren. Dieser Designansatz wird eher selten verwendet.

Was der Controller ist? Er ist eine Abstraktionsschicht, mit der die Flexibilität gewährleistet wird. Der Controller *interpretiert* die Eingabe um anschließend das Model auf Basis dieser Eingabe zu manipulieren. Das könnte man natürlich direkt im View-Code machen, aber zum Einen bläht das die View auf, die nun neben der Manipulation der Benutzerschnittstelle auch für die Steuerungslogik des Models zuständig ist und zum Anderen, das ist das Entscheidende, die View wird direkt an das Model gekoppelt. Wenn ich die View nun mit einem anderen Model verwenden will, kann ich das vergessen.

Auch die Steuerungslogik kann ich nun leicht abändern, indem ich einfach den Controller austausche.

Wenn man verstanden hat was MVC ist, dann ist das alles sehr einleuchtend und in keinster Weise kompliziert.


----------



## Marco13 (3. Apr 2009)

Stefan S. hat gesagt.:


> Eines steht aber fest, der Controller ist nie der Observable!



Ja, ist alles eben zu schwammig. Ich hatte ja gesagt, dass mir auch kein Grund einfällt, den Controller Observable zu machen, aber man könnte es... in einem Fall, der auch mit dem Teil zusammenhängt:



Stefan S. hat gesagt.:


> ...
> die View wird direkt an das Model gekoppelt. Wenn ich die View nun mit einem anderen Model verwenden will, kann ich das vergessen.



Ich gehe davon aus, dass das Model in den meisten Fällen ein Interface sein sollte. Und das Interface definiert man nicht zuletzt, um von der Implementierung unabhängig zu sein. Es ist zwar realisitisch (und nicht zuletzt eines der Ziele von MVC) dass man mehrere, ggf. verschiedene Views für dasselbe Modell haben kann, aber dass eine View wirklich _verschiedene_ Modelle darstellen soll, erscheint mir etwas weit hergeholt. Ein JTree zeigt nie ein TableModel an, sondern immer eine Baumstruktur, die durch das Interface TreeModel spezifiziert ist. Ein Slider zeigt keinen Text an, sondern einen Wert in einem bestimmten Bereich, wie es im Interface BoundedRangeModel definiert ist. Das ist eben einfach so. Wenn sich das Modell-Interface ändert, dann ändert das (imho zwangsläufig) auch die View - nach deiner Argumentation müßte man bei einer Änderung des Modells die Änderungen eben (nicht in der View sondern schlicht und einfach) im Controller machen - dass das weniger aufwändig ist, oder dass es erstrebenswert ist, die View beizubehalten, kann ich mir kaum vorstellen. Effektiv würde damit das neue Modell durch den Controller ja nur "umgebogen", so, dass es "aussieht" wie das alte Modell - und da schließt sich der Kreis zum Observablen Controller von oben: Theoretisch (!!!) könnte man natürlich auch den Controller das Modell-Interface implementieren lassen - das Controller könnte (theoretisch!!!) einfach eine Implementierung des Modelles sein, und müßte demnach auch Observable sein. Nur theoretisch - eine sinnvolle Anwendung dafür würde mir spontan nicht einfallen, aber dadurch, dass das Modell nur ein Interface ist, und die View nur dieses Interface kennt (also nicht weiß, dass das, was sie da als Modell sieht, eigentlich der Controller ist) wäre das IMHO zumindest legitim... nicht unbedingt sinnvoll, und irgendwie komisch, aber ... legitim....


----------



## Stefan S. (3. Apr 2009)

Marco13 hat gesagt.:


> Ja, ist alles eben zu schwammig. Ich hatte ja gesagt, dass mir auch kein Grund einfällt, den Controller Observable zu machen, aber man könnte es...



Ja, man _könnte_ es. Die Frage ist aber, ob man etwas tut, weil man es tun kann oder ob man es tut, weil es sinnvoll ist. Diese Entscheidung überlasse ich dem Entscheidungsträger.



Marco13 hat gesagt.:


> Ich gehe davon aus, dass das Model in den meisten Fällen ein Interface sein sollte. Und das Interface definiert man nicht zuletzt, um von der Implementierung unabhängig zu sein.



Das ist in der Tat richtig. Wenn das Modell ein Interface ist, ist es prinzipiell stets möglich über das Adapter Muster die Implementierung zu variieren.



Marco13 hat gesagt.:


> Es ist zwar realisitisch (und nicht zuletzt eines der Ziele von MVC) dass man mehrere, ggf. verschiedene Views für dasselbe Modell haben kann, aber dass eine View wirklich _verschiedene_ Modelle darstellen soll, erscheint mir etwas weit hergeholt.



Weit hergeholt ist natürlich subjektiv zu bewerten. Ich hatte schon die ein oder andere Applikation, die verschiedene Modelle darstellte. Natürlich ist eine View das Abbild des Modells und daher in gewissem Maße auch daran gekoppelt.



Marco13 hat gesagt.:


> Wenn sich das Modell-Interface ändert, dann ändert das (imho zwangsläufig) auch die View



Sofern man die Entkoppelung zwischen View und Modell weitestgehend aufrecht erhält, muss die View keineswegs geändert werden, sollte sich das Modell ändern. Wenn man allerdings in der View direkt gegen das Modellinterface programmiert, dann ist das natürlich korrekt.



Marco13 hat gesagt.:


> nach deiner Argumentation müßte man bei einer Änderung des Modells die Änderungen eben (nicht in der View sondern schlicht und einfach) im Controller machen - dass das weniger aufwändig ist, oder dass es erstrebenswert ist, die View beizubehalten, kann ich mir kaum vorstellen.



Ggf. das wir gegen ein interface programmieren, ja. Die Änderungen müssen dann im Controller erfolgen. Ich sagte ja bereits das der Controller eine Kernaufgabe implementiert. Wenn ich den ganzen Kram in die View verschiebe, habe ich zwei Aufgabenbereiche in der View. Abstraktionstechnisch kein guter Ansatz. 

Der Trick bei der Sache ist, das ich dank Controller auch gleichzeitig die Steuerungslogik voll austauschbar mache. Programmiere mal ein Spiel und du wirst das zu schätzen wissen.

Wie dem auch sei, es ging in der Diskussion um das *Observable*. Fällt dir irgendein plausibler Grund ein, den Controller zum Observable zu machen? Mir jedenfalls nicht und bisher habe ich das auch noch nirgendwo sehen können, bis auf diesen ominösen FAQ Eintrag hier.


----------



## Wildcard (3. Apr 2009)

Stefan S. hat gesagt.:


> Der Controller kann aber in einigen Designs auch zum Observer werden, z.B. um bei Änderungen der Daten direkt die View zu manipulieren. Dieser Designansatz wird eher selten verwendet.


Nicht im geringsten. Bei GEF ist das Standard und es gibt tonnenweise GEF Editoren in the wild. Bei Swing ist es genauso Standard, oder ist ein Renderer ein Observer?


----------



## Stefan S. (3. Apr 2009)

Wildcard hat gesagt.:


> Nicht im geringsten. Bei GEF ist das Standard und es gibt tonnenweise GEF Editoren in the wild. Bei Swing ist es genauso Standard, oder ist ein Renderer ein Observer?



Und? Ich hatte bereits darauf hingewiesen das ein Controller auch zum Observer werden kann. Du stimmst mir also zu. Gut!


----------



## Wildcard (3. Apr 2009)

Ich sage nur, das diese Form alles andere als selten ist.


----------



## Stefan S. (3. Apr 2009)

Wildcard hat gesagt.:


> Ich sage nur, das diese Form alles andere als selten ist.



Ich schrieb "eher selten". Wir hatten doch schon eine Diskussion über absolute Adjektive. Welches Adjektiv soll ich nun deiner Ansicht nach für den Nebensatz verwenden, weniger oder vielleicht  mittelmäßig oft?


----------



## André Uhres (4. Apr 2009)

Stefan S. hat gesagt.:


> Eines steht aber fest, der Controller ist nie der Observable! ...Der Controller interpretiert die Eingabe um anschließend das Model auf Basis dieser Eingabe zu manipulieren.


Frage: wenn der *Controller* das Model manipuliert, ist es dann nicht sinnvoll für ihn, *Observable* zu sein, damit er seine Observer über diese Manipulationen direkt informieren kann, also ohne den Umweg über das Model? Bei den Anwendungen, mit denen ich zu tun habe, kann das Model sich eh nicht intern periodisch selbst verändern.


----------



## mvitz (4. Apr 2009)

André Uhres hat gesagt.:


> Frage: wenn der *Controller* das Model manipuliert, ist es dann nicht sinnvoll für ihn, *Observable* zu sein, damit er seine Observer über diese Manipulationen direkt informieren kann, also ohne den Umweg über das Model? Bei den Anwendungen, mit denen ich zu tun habe, kann das Model sich eh nicht intern periodisch selbst verändern.



Das hatte ich mir auch schon überlegt, aber dann müsste ja jede View, die das Model anzeigen möchte einen Controller haben auch, wenn die View garnichts verändern kann. Ist das Model Observable braucht sie nur das Model kennen.


----------



## SlaterB (4. Apr 2009)

die View hat nur einen Listener, ein Interface wie TableModelListener, 
welche Klasse den befüttert ist der View egal, bekommt sie auch nicht mit,
die Informationen zur Darstellungsänderung kommen entweder direkt aus dem Event oder aus dem konfigurierten Model der View, 
wiederum unabhängig davon, wer das Event sendet

ich sehe keinen 'Umweg', das Model muss eh (vor dem Event) aktualisiert werden, was spielt es für eine Rolle, ob das Model oder der Aufrufer danach die Events losschickt?
interessanter wirds schon, wenn mehrere Stellen das Model ändern können, entweder macht es genau das eine Model, oder jeder Aufrufer muss sich einzeln darum kümmern..

andersrum könnte man vielleicht argumentieren, wenn ein Controller gleich 10 Models ändert und die nicht alle einzeln Events schicken sollen, sondern der Controller das besser koordinieren kann


----------



## Gast2 (4. Apr 2009)

Stefan S. hat gesagt.:


> Ja genau. Du und die FAQ gegen den Rest der Welt.
> 
> Mach nur so weiter, mir ist das vollkommen egal.
> 
> ...



LOL???WTF??? 
Wenn für dich runterlabern eine Beleidigung ist dann weiß ich auch nicht :lol::lol:
Wie gesagt du hast mir keine Argumente geliefert
Argument ? Wikipedia, nur gesagt das ist so und nirgends standen Nachteile es  anders zu machen...
Solltest ein bischen besser lesen... wie gesagt hab ich deine links verstanden, da aber nirgends irgendwo stand was der Nachteil ist hab ich nachgefragt und deine Antwort ist kein MVC --->HAMMER ARGUMENT 
Viel Spaß beim Schmorren


----------



## André Uhres (4. Apr 2009)

SlaterB hat gesagt.:


> andersrum könnte man vielleicht argumentieren, wenn ein Controller gleich 10 Models ändert und die nicht alle einzeln Events schicken sollen, sondern der Controller das besser koordinieren kann


Ja, genauso hatte ich das verstanden: ein Model wird nur über den Controller verändert und der informiert dann die Views und gewährleistet notwendige Koordinationen. Das scheint mir zumindest eine sinnvolle Alternative zu sein. Es wäre allerdings gut, wenn die MVC-Beschreibung aus den FAQ die möglichen Alternativen erwähnen würde, mit den jeweiligen Vor- und Nachteilen.


----------



## Marco13 (4. Apr 2009)

... und der "Nachteil" bei dieser Variante wäre eben, dass man sicherstellen muss, dass das Modell garantiert nur von diesem einen Controller verändert wird. (Das ist kein "Nachteil", sondern ggf. nur eine Einschränkung in bezug auf die mögliche Anwendung)


----------



## Stefan S. (6. Apr 2009)

André Uhres hat gesagt.:


> Frage: wenn der *Controller* das Model manipuliert, ist es dann nicht sinnvoll für ihn, *Observable* zu sein, damit er seine Observer über diese Manipulationen direkt informieren kann, also ohne den Umweg über das Model? Bei den Anwendungen, mit denen ich zu tun habe, kann das Model sich eh nicht intern periodisch selbst verändern.



Das könnte man bei ganz *trivialen* Modellen in der Tat machen. Allerdings unterminiert es den Sinn und Zweck von MVC, da das Modell die Daten beherbergt und daher die Observer sich dort registrieren sollten um von Änderungen bei diesen Daten direkt informiert zu werden. 

Macht man den Controller Observable, registriert sich die View direkt beim Controller, im Prinzip ist der Controller nun für die Steuerung zuständig und - was nicht zielführend ist - zusätzlich für die korrekte Synchronisation des Datenbestandes mit der View.

Wie gesagt, bei trivialen Modellen ist das möglich, allerdings auch dann wenig sinnvoll.



SirWayne hat gesagt.:


> LOL???WTF???
> Wenn für dich runterlabern eine Beleidigung ist dann weiß ich auch nicht :lol::lol:
> Wie gesagt du hast mir keine Argumente geliefert
> Argument ? Wikipedia, nur gesagt das ist so und nirgends standen Nachteile es  anders zu machen...
> ...



Du bist schon selten dämlich. Das beweisen allein deine unzähligen, überflüssigen Interpunktionszeichen, garniert mit den drolligen Smilies. 

Unter http://www.java-forum.org/504832-post84.html habe ich es dir breit und sorgfältig erklärt und zusätzlich mit 10 weiterführenden Links untermauert, offensichtlich ist die Begriffstutzigkeit bei dir ganz extrem ausgeprägt.

Naja, die Normalverteilung ist ja schließlich keine senkrechte Linie, so dass es auch Individuen am linken Spektrum geben muss.


----------



## Gast2 (6. Apr 2009)

> Du bist schon selten dämlich. Das beweisen allein deine unzähligen, überflüssigen Interpunktionszeichen, garniert mit den drolligen Smilies.
> 
> Unter http://www.java-forum.org/504832-post84.html habe ich es dir breit und sorgfältig erklärt und zusätzlich mit 10 weiterführenden Links untermauert, offensichtlich ist die Begriffstutzigkeit bei dir ganz extrem ausgeprägt.
> 
> Naja, die Normalverteilung ist ja schließlich keine senkrechte Linie, so dass es auch Individuen am linken Spektrum geben muss.



Naja dämlich vielleicht schon, aber ob diese Eigenschaft selten ist waage ich mal zu bezweifeln .
Aber wenn du schon so klug tust/bist, könnte man doch glatt erwarten , dass du 2 Datumsangaben vergleichen kannst???:L. Dann schau mal wann dein Beitrag(http://www.java-forum.org/504832-post84.html) gepostet wurde und wann ich zu dir gesagt habe dass du keine Argumente geliefert hast. Doch immer wieder schön zu sehen, wie Leute wenn Sie sich angegriffen fühlen ohne nachzudenken reagieren


----------



## André Uhres (6. Apr 2009)

Stefan S. hat gesagt.:


> Macht man den Controller Observable, registriert sich die View direkt beim Controller, im Prinzip ist der Controller nun für die Steuerung zuständig


Im allgemeinen versteht man unter "Controller" ein Ding, mit dem man andere Sachen *steuern* kann, nicht wahr? Insofern ist es wohl eher sinnvoll, wenn er die Steuerung übernimmt. Daß dadurch das MVC Konzept untermininiert wird, wage ich zu bezweifeln, da es sich lediglich um eine triviale Funktionsverlagerung handelt und das grundlegende Konzept dadurch nicht aufgegeben wird.


----------



## Stefan S. (6. Apr 2009)

André Uhres hat gesagt.:


> Im allgemeinen versteht man unter "Controller" ein Ding, mit dem man andere Sachen *steuern* kann, nicht wahr? Insofern ist es wohl eher sinnvoll, wenn er die Steuerung übernimmt. Daß dadurch das MVC Konzept untermininiert wird, wage ich zu bezweifeln, da es sich lediglich um eine triviale Funktionsverlagerung handelt und das grundlegende Konzept dadurch nicht aufgegeben wird.



Ich habe die Argumente breit und ausführlich erörtert und auch aufgezeigt, warum das Modell in allen mir bekannten Anwendungen das Observable darstellt. Wir hatten uns ohnehin bereits darauf verständigt das der Controller im besten Fall nur bei *trivialen* Modellen, die intern keinen eigenen Zustandsänderungen unterliegen, der Observable sein kann. 

Untermauert habe ich meine Ansichten durch zahlreiche externe Quellen, wie es von Softwareentwicklern rund um den Globus gehandhabt wird. Wenn du weiterhin stringent an deiner eigenwilligen "Interpretation" festhalten möchtest, ist und soll das weiß Gott, nicht mehr mein Problem sein.


----------



## André Uhres (6. Apr 2009)

Stefan S. hat gesagt.:


> Wenn du weiterhin stringent an deiner eigenwilligen "Interpretation" festhalten möchtest, ist und soll das weiß Gott, nicht mehr mein Problem sein.


Ich will nur offen sein für sinnvolle Alternativen und nicht unbedingt _an einer eigenwilligen "Interpretation" festhalten_. Wenn ich keine Alternativen gelten lassen wollte, wäre ich wohl eher eigenwillig.


----------

