Dieses Blog durchsuchen

Donnerstag, 25. März 2010

"Caller - Mediator - Listener" im Detail

In meinem ersten Beitrag hatte ich die Idee des "Caller - Mediator - Listener" Triplets kurz erklärt. Nun möchte ich dieses im Detail erläutern und erklären, was ich mir dabei gedacht habe.

Der Grundgedanke, den ich hatte, war letztlich gar nix weltbewegend Neues.
Ich habe einfach den Sachverhalt der Objektkommunikation aus der objektorientierten Programmierung wörtlich genommen.
Somit gibt es eben:
  • einen Caller, der etwas zu sagen hat
  • einen Mediator, der die Botschaft vom Caller empfängt und weiterleitet
  • einen Listener, der letztlich die Nachricht empfängt und die eigentlichen Befehle durchführt
Damit das ganze noch anschaulicher wird, habe ich eine Präsentation erstellt. Ich hoffe, es ist anschaulich genug.
(Da es sich aber hierbei um eines der einfachsten der insgesamt 3 Triplets handelt, sehe ich da keine Probleme.)


So, die nächsten beiden Triplets werden auf jeden Fall interessanter, denn da werden Daten übertragen! Da gibt es dann auch schönere Anwendungsbeispiele.
Als Vorlage werde ich gleich wieder diese Präsentation verwenden, dann bereitet es nicht ganz so viel Arbeit.

PS.:
Alle Dateien, die hinsichtlich dieses Blogs anfallen, findet man auch in einem öffentlichen Ordner: KLICK

Montag, 22. März 2010

Es dauert noch etwas ...

Eigentlich wollte ich die 3 Triplets heute in einem Beitrag in Textform erklären.
Mir kam aber eine bessere Idee in den Sinn!
Da Bilder bekanntlich mehr sagen, als 1000 Worte, beschloss ich diese Triplets mithilfe einer Präsentation zu beschreiben.
Dazu verwende ich Google Text & Tabellen.
Es funktioniert bis jetzt alles wunderbar und auch die grafischen Funktionen machen keine Probleme.

Man darf sich also auf 3 anschauliche Präsentationen freuen. (Zumindest hoffe ich, dass sie anschaulich genug sein werden. *g*)

Das ganze ist jedoch etwas aufwändig. Aber sobald die erste Präsentation fertig ist, werde ich sie hier im Blog veröffentlichen. Bis dahin bitte ich um etwas Geduld! :-)

Sonntag, 21. März 2010

Presenter First - Geniale Idee!

Meinen ersten Beitrag beginne ich sogleich mit einem Konzept, welches sich "Presenter First" nennt. Ich möchte hier nicht die Grundlagen dessen ausschweifend erklären.
Hierzu verweise ich lieber auf zwei Dokumente von den eigentlichen "Erfindern".

Da wäre zunächst das eigentliche Paper, welches die Sache konzeptionell erklärt:
Presenter First: Organizing Complex GUI Applications for Test-Driven Development [pdf] [doc01]

Und dann noch ein eher praktisches Beispiel, welches in dem Magazin "Better Software" erschien:
Big, Complex, and Tested? Just Say ‘When’ [pdf] [doc02]

Nun, als ich das erste mal von diesem Konzept hörte, war ich von dieser Idee total angetan.[1]
Man stellt sich dann aber dennoch die Frage: "Wo fange ich da nun am besten an, meine Software zu entwerfen?"
Klar, bei dem gewünschten Feature. Das ist ja der Sinn von dem Konzept.
Das mag auch noch einfach sein, wenn das Feature in etwa so aussieht: "Wenn ich auf den Button [Beenden] klicke, soll die Anwendung beendet werden."
Das ist auch soweit einfach, wenn hierbei wirklich nur die Anwendung beendet werden soll und sonst nix weiter.
Was aber, wenn mit diesem einfachen Feature komplexe Aufräumarbeiten verbunden sind? Vielleicht soll der Benutzer noch gefragt werden, ob sein geändertes Dokument vorher gespeichert werden soll? Etc.
Da ist das zuerst genannte Feature die höchste Abstraktionsebene.
Aus der "Presenter First"-Sicht ist das im Grunde auch so richtig. Was mit dem Beenden-Vorgang sonst noch zusammen hängt, interessiert in dieser Abstraktionsebene überhaupt nicht. Das ist ja auch Sinn und Zweck dieser strikten Entkopplung.
Es stellt sich daher die Frage: "Wie tief und fein sollte die Abstraktion sein? Das heißt, erstelle ich sehr viele kleine Sub-Presenter, oder sollte das an der Stelle doch etwas grober ausfallen?"

Desweiteren stand ich schon vor folgendem Problem:
Sollte zu jedem Presenter auch nur ein Fenster/Dialog gehören? Oder sollte jeder Button/jede Komponente einen eigenen Presenter bekommen?
Ersteres macht die ganze Sache sehr einfach und übersichtlich, ist aber sehr unflexibel und problematisch, wenn man z.B. noch einen Adapter oder generell noch weitere Abstraktionsebenen zwischen eine einzelne Komponente des User Interfaces schalten will.
Bei der anderen Variante gäbe es nicht dieses Problem. Aber hier hat man am Ende Unmengen einzelner Schnittstellen-, Presenter-, Model- und View-Klassen.

Nun, die Erfinder meinen hier, man solle logisch zusammengehörige Komponenten gemeinsam mit einem Presenter verbinden.
Klar, das ist erstmal ein guter Kompromiss. Da könnte man die Komponente, welche noch weitere Adapter braucht, entsprechend separieren und die anderen Komponenten zusammen halten.
Allerdings ist mir das zu willkürlich.

Und das ist gleich das Nächste. Die Willkürlichkeit, wie die Model-View-Presenter-Einheiten zusammengesetzt sind. Das heißt, bei dem originalen Konzept sieht man nicht direkt von Außen, wie der Daten- und Nachrichtenfluss verläuft. Das heißt, jemand, der den Quellcode zum ersten Mal sieht, wird nicht auf Anhieb wissen, was dieses Model oder jene View macht oder welche Rolle der Presenter dabei spielt.
Dazu müsste man sich nämlich erst tiefer in den Quellcode einlesen.

Ich grübelte noch einige Zeit über die oben genannten Probleme. Immer wieder las ich mir die Dokumente durch.
Irgendwann ließ ich mir folgenden Text [doc02; letzte Seite unten] so richtig auf der Zunge zergehen:
The “micro-architecture” of Presenter First is like a carbohydrate chain in organic chemistry — interesting functionality arises from applying the same basic pattern of object composition. The mechanisms and domain may vary, but the core principles do not: When the customer says “when,” write it into a presenter.
Dann war es mir klar. Was dieses an sich tolle Konzept brauchte, war eine gewisse Ordnung in dem willkürlichen Chaos. So, wie auch die Moleküle oder die Zellen des Menschen nach einer gewissen Ordnung funktionieren.
Ich übertrug den Ordnungsbegriff auf die Softwareentwicklung und kam dann zu folgender Lösung:

Jedes Objekt übernimmt einen sehr kleinen Aufgabenbereich in dem Gesamtsystem. Ein Button im UI wird höchstens nur als Auslöser für eine komplexe Aufgabe dienen. Vielleicht empfängt er auch mal Daten in Form einer neuen Beschriftung oder anderer Eigenschaftswerte. Aber in erster Linie wird er nur zum Triggern da sein.

Somit übernimmt der Button eine entscheidende Aufgabe: Er ist ein Caller!
Aber ein Caller alleine bringt leider nicht viel. Es muss auch jemand auf das bestimmte Signal hören, was der Caller ausgesandt hat. Also muss es noch einen Listener geben.
Aber da fehlt noch einer! Caller und Listener sollen ja nix voneinander wissen. Ein Presenter muss immer existieren, der beide miteinander verbindet. Aber die Bezeichnung "Presenter" passt hier nicht gut. Zwischen einem "Rufer" und einem "Zuhörer" muss noch jemand vermitteln. Dies wäre im klassischen Sinne die "Luft". "Air" klingt aber komisch, weshalb ich mich hier für Mediator entschieden habe.

Das ist nun also die erste Triplet-Gruppe von insgesamt 3 Gruppen, die ich mir ausgedacht habe, um ein bisschen Ordnung und Struktur in die Sache zu bekommen.

Caller - Mediator - Listener

Die anderen Beiden nenne ich jetzt erstmal so, ohne Erläuterung.

Transmitter - Frequency - Receiver
und
Client - Provider - Server

In den nächsten Beiträgen werde ich diese 3 Triplets genauer beleuchten.
(Theoretisch sollte sich schon die Funktion der letzten 2 Triplets anhand der Bezeichnungen erahnen lassen. *g*)

Das soll es aber erstmal für heute gewesen sein.


  1. Und ich bin noch immer davon begeistert. Doch ich habe noch so ein paar Schwierigkeiten damit, weshalb ich dieses Konzept noch nicht auf Arbeit verwende. Das werde ich aber in diesem und weiteren Blogbeiträgen nach und nach erläutern.