Model-View-Controller: ---------------------- Idee: Trennung der Objekte, die die Logik der Applikation und die Daten repr"asentieren von der konkreten Darstellung der Daten und der Manipulation der Daten. Eingabeger"ate, Ausgabeger"ate, Tastatur, Maus etc. ==> Controller <----> View ==> Bildschirm, Drucker etc. Klassen InputState und | | WWW (HTML) InputSensor | | Klasse GraphicsContext |> <| Model Daten, Applikation Der Controller wandelt Tastatureingaben und Mausbewegungen in Nachrichten an das Modell um. Daf"ur versteht der Controller die Nachricht controlActivity. Die View stellt den Zustand des Modells auf dem Bildschirm oder einem anderen Ausgabeger"at dar. Dazu wird bei Bedarf der entsprechenden View die Nachricht displayOn: aGraphicsContext geschickt. Vorteile: - Erlaubt die Anpassung an verschiedene Ein-/Ausgabeger"ate (X-Terminal, Ascii-Terminal, WWW (HTML)). - Anpassen der Benutzerschnittstelle an unterschiedliche Benutzer (Experten, Anf"anger). - Erlaubt (auch gleichzeitig) unterschiedliche Sichtweisen auf die Daten (Liste von Zahlen, Balkendiagramm etc). Datenflu"s: Der Controller erzeugt aus dem Zustand der Eingabeger"ate Nachrichten, die den Zustand des Modells "andern k"onnen. Die View 'beobachtet' die View und zeigt die "Anderungen auf dem Bildschirm an. Der Controller fordert die View _nie_ selbst dazu auf, den Zustand des Modells neu anzuzeigen. Der Controller wei"s "uber die View um z.B. festzustellen ob sich die Maus in einem Bereich des Fensters befindet, f"ur den z.B. Tastatureingaben eine bestimmte Bedeutung haben. Z.B. wird die Reaktion auf eine Tastatureingabe in einem Textbereich anders aussehen als die Reaktion auf eine Tastatureingabe, wenn sich die Maus "uber einer Darstellung einer Liste befindet. Beispiel: Widerstand und WiderstandsView Problem: Wie erfahren Controller und View, da"s sich der Zustand der Eingabeger"ate und der des Modells ge"andert haben? a) Polling: St"andiges Abfragen des Zustandes. Das macht der Controller. b) Versenden von speziellen Nachrichten, wenn sich der Zustand "andert. Das macht ein Modell. Broadcast Nachrichten --------------------- Unterschied zu normalen Nachrichten. - Der Empf"anger der Nachricht ist nicht bekannt. sender changed: aspect with: parameter - Es kann mehrere Empf"anger f"ur eine Nachricht geben. Der Empf"anger mu"s sich ausdr"ucklich f"ur Broadcast Nachrichten von einem Objekt interessieren. sender addDependent: empf"anger sender removeDependent: empf"anger - Der Empf"anger entscheidet selbst ob er auf eine Broadcast (Bc) Nachricht von einem Objekt reagieren will. Der Empf"anger implementiert die Methode update:with: Jedes Objekt kann Broadcast Nachrichten verschicken und Empfangen. Technik: Dem Sender ist eine Liste von abh"angigen Objekten zugeordnet (self dependents). Schickt sich ein Objekt die Nachricht self changed: aspect with: parameter, dann wird self dependents do: [:each| each update: aspect with: parameter] ausgef"uhrt. Es gibt zwei Arten wo Abh"angigkeiten gespeichert sind: a) In einer globalen Variablen (Klassenvariable DependentFields in Object). Hier gibt es ein Problem mit Garbage. Wird eine View auf ein Model geschlossen, mu"s sich die View aus der Liste der Abh"angigen des Modells austragen, ansonsten wird die View von einer globalen Variablen referenziert und _nicht_ vom Garbage Collector als Garbage erkannt. b) In einer Instanzvariablen dependents (f"ur Unterklassen der Klasse Model) D.h. Objekte, die als Modelle im MVC Konzept agieren sollen, sollten bevorzugterweise eine Unterklasse der Klasse Model sein. ---------------------------------------- Eine View kann aus mehreren Komponenten (wieder Views) bestehen, die Teilaspekte des Modells zeigen. Diese Views k"onnen nat"urlich einfacher sein als eine View, die gleichzeitig f"ur alle Aspekte verantwortlich ist. In der Regel stellt eine View den Aspekt auf einer rechteckigen Fl"ache dar. Eine CompositeView f"ugt die einzelnen Views zu einer Gesamtview zusammen. Jede View hat ihren eigenen Controller. Beispiel: WiderstandsView2, Eine View f"ur die Spannung, eine f"ur den Strom etc. Jedes Smalltalkfenster hat als oberste View ein Instanz der Klasse ScheduledWindow und als Controller eine Instanz der Klasse StandardSystemController. Kontrollflu"s (View-Seite) -------------------------- Das Modell enth"alt eine Nachricht und schickt daraufhin die Nachricht changed:with: an sich selbst. Dadurch werden die Nachrichten update:with: an die abh"angigen Objekte (Dependents) geschickt. Ist einer der abh"angigen Objekte eine View und interessiert sie sich f"ur den Aspekt des Model's in der update:with: Nachricht, dann schickt sie in der Regel die Nachricht invalidate an sich selbst, was dazu f"uhrt, da"s eine damage event registriert wird. Dabei wird in der Regel die View noch nicht neu gezeichnet. Erst wenn die Nachricht checkForEvents einem Controller geschickt wird, werden alle Sch"aden der View repariert. Kontrollflu"s (Controller-Seite) -------------------------------- aControlMangager (ScheduledControllers): activeControllerLoop -> aStandardSystemController isControlWanted? (Die Maus ist im Fenster/View) aController: startUp -> controlLoop -> i) controlActivity -> controlToNextLevel oder eine andere Aktion, wie Mausaktionen (yellowButtonActivity) -> Nachrichten an das Model -> aModel changed:with: -> aView update:with: -> aView invalidate !!Dauert das Beantworten der Nachricht lange, dann scheint das Smalltalkinterface eingefroren zu sein, d.h. kein anderer Controller bekommt die Chance etwas zu tun und es wird kein checkForEvents durchgef"uhrt und deshalb bei Bedarf die Fenster nicht neu gezeichnet. Die Fenster werden auch dann nicht neu gezeichnet, wenn das Modell immer wieder changed: und die View daraufhin invalidate Nachrichten schickt. Solange kein checkForEvents aufgerufen wird, werden die Fenster nicht neu gezeichnet. M"ogliche L"osung: Die View schickt die Nachricht 'self invalidateRectangle: self bounds repairNow: true'!! ii) poll -> checkForEvents (hier erst werden die Fenster neu gezeichnet) & anInputState pollForActivity anInputSensor/anInputState: bekommt pollForActivity -> h"alt den aktuellen Proze"s an, wenn l"angere Zeit keine Events gekommen sind. ---------------------------------------- In ControlManager>activeControllerLoop wird st"andig nach einem Smalltalkfenster gesucht, das die Kontrolle haben will (das hei"st in der Regel, das das Fenster die Maus enth"alt). Der Controller reicht die Kontrolle an die Controller seiner Teilviews weiter, bis einer dieser Controller eine Aktion ausf"uhrt (z.B. ein PopUpMenu erzeugt) und Nachrichten an das Modell schickt. ---------------------------------------- Wiederverwendung ---------------- Vererbung: Wiederverwendung von Klassen plus "Anderung des Verhaltens. Benutzen von Komponenten: Zusammenbau eines Systems aus Standardkomponenten. Aspekt Adaptoren: - wandeln Nachrichten um: value in und value: in : - leiten Broadcast Nachrichten weiter und wandeln dabei ebenfalls das Aspectsymbol. Beispiel: WiderstandsApp3