Sinn und Grenzen eines Fluent Interfaces

Auf der JAOO hatte ich das Glück ein Tutorial zum  Thema domänenspezifische Sprachen (Domain Spezific Language – DSL) besuchen zu können. Interessant war es, die verschiedenen Elemente des Themas einmal in einen Zusammenhang gebracht zu bekommen. Und wie immer, wenn Martin Fowler etwas darstellt, bekommt man ein paar neue Begriffe beigebracht, die es erlauben das bisher Gesehene und Gefühlte besser zu benennen und in einen systematischen Zusammenhang zu stellen.

Fluent Interfaces sind eine Form einer DSL, genauer einer internen DSL, genauer: sie sind ein syntaktisches Mittel eine interne DSL zu realisieren. Und Fluent Interfaces sind angesagt. Ich habe gesehen wie in einigen Projekten mithilfe eines Fluent Interfaces ein Bereich modelliert wurde. Mein Arbeitsfeld ist der eCommerce und so sind es oftmals Regeln, die den Checkout-(Bezahl-)Prozess steuern, die so modelliert werden. Ich kenne diese Form des Interfaces aber auch aus Konvertern, die eine Form von Daten in eine andere übersetzen. Bisher, vor dem Tutorial, hatte ich ein ungutes Gefühl, wenn ich die Beschreibung der Regeln in einem Fluent Interface sah und die Implementierung der Regeln mit der Interpretation der internen DSL verbunden war. Seitdem, seit dem Tutorial, kann ich das etwas genauer beschreiben. DSLs seien, so Fowler, dafür da ein Semantisches Modell zu instantiieren. Das Sematische Modell modelliere den Gegenstandsbereich. Es sei kein Domänenmodell, weil auch Bereiche, die nicht zur Domäne gehörten, mit einer DSL modelliert werden könnten. (Insofern sei aber jedes Domänenmodell ein Semantisches Modell.) Nehmen wir das Beispiel des Regelwerks für einen Checkoutprozess. Ich brauche ein Sematisches Modell, das meine Regeln, meine Lieferzeiten, meine Bezahlarten modelliert. Dieses Modell ist als solches testbar. Um jetzt für einen konkreten Shop ein spezifisches Regelwerk zu instantiieren, benutze ich eine DSL. Die kann ich ebenfalls separat testen. Der Test besteht darin, zu kontrollieren ob eine bestimmte Beschreibung eine bestimmte Form des Regelwerkes instantiiert. Der Test ist vollständig entkoppelt vom Test der Funktion des Regelwerks. Das entscheidende in diesem Zusammenhang ist das Sematische Modell. Es ist substantiell, dass hier der Bereich, der abgebildet werden soll, möglichst explizit modelliert ist. Ich kenne Implementierungen, die die DSL nutzen um eine sehr allgemeine Datenstruktur zu befüllen, bspw. einen Hash, und diese dann in entsprechend imperativen Code nutzen. Hier ist die DSL eher kontraproduktiv, weil sie verdeckt, dass die Domäne nicht wirklich modelliert wurde. Durch die DSL entsteht der Eindruck, es gäbe die Konstrukte, die die Domäne abbilden.

Der Sinn einer DSL lässt sich, Fowler folgend, auch so beschreiben: Anstatt das Command/Query-API des Sematischen Modells zu benutzen, wird eine Fluent Interface eingesetzt, um das Modell zu popularisieren.Das Semantische Modell stellt ein alternatives Berechnungsmodell dar – bspw. ein Regelwerk. Wird das Command/Query-API dieses Modells benutzt, ist das alternative Programm – implizit in der Instantiierung des konkreten Regelwerks enthalten – unsichtbar. Die DSL erlaubt es das alternative Programm als solches sichtbar zu machen.

(Fussnote: Wer mit einer internen DSL programmiert hat oftmals das Gefühl einem deklarativeren Programmierstil zu folgen. Das liegt nicht daran, dass DSLs per se einem deklarativeren Programmierstil folgen, sondern daran dass ein Semantisches Modell instantiiert wird, welches ein regelorientiertes Paradigma ausdrückt.)

Ein ganz kleines Beispiel: Mocha, die Ruby-Mock-Library, mit einem fiktiven Command/Query-API. Hier wird ein Mock programmiert.

# Command/Query-API
object = mock()
expectation = object.create_expectation()
expectation.set_method_name(:expected_method)
expectation.set_parameters([:p1, :p2])
expectation.set_return_value(:result)

Das Gleiche als interne DSL (mit Original-Mocha-Syntax)

# Fluent Interface
object = mock()
object.expects(:expected_method).with(:p1, :p2).returns(:result)

Im zweiten Fall ist die Programmierung des Mocks deutlich zu erkennen. Seine Programmierung nähert sich dem programmierten Methodenaufruf an. Im ersten Fall muss ich mir den zu erwartenden Methodenaufruf beim Lesen im Kopf zusammensetzen.

(Fussnote: Der Begriff Command/Query-API meint ein sinnvolles Prinzip für die Konstruktuion von Objekten. Eine Methode sollte entweder eine Query sein, das bedeutet, sie liefert einen Wert zurück und ändert den Zustand des Objektes nicht, oder ein Command, was bedeutet, dass die Methode eine Zustandveränderung des Objektes bewirkt, aber keinen Wert zurückliefert (Javasprech: void). Ein Fluent Interface gegen die Unterscheidung, weil es in der Regel den Zustand eines Objektes verändert und das Objekt zurückliefert, damit solche Methodenketten wie oben möglich werden.)

Platzen oder Lean & Zen

Ich habe manchmal das Gefühl, ich platze gleich, wenn ich eine Idee nicht loswerde, wenn ich nicht über etwas reden kann, was mich gerade bewegt.

Ich bin im Moment in Arhus und habe an der JAOO teilgenommen. Die ersten Tage waren so lala. Das mag an mir liegen. Ich hatte mir vor allem Talks ausgesucht, bei denen ich schon etwas von den Sprechern gelesen hatte. Ich wollte sie gerne mal live sehen und als Mensch erleben. In der Regel finde ich das sehr spannend, weil mein Bild von dem, was sie schreiben, sich präzisiert. (So ist es mir bspw. auch mit der Stimme von Stefan Tilkov gegangen, seitdem ich ihn beim heise-Developer-Podcast gehört habe, lese ich seinen Blog ganz anders.) Nun denn – ich habe die Leute jetzt gesehen, habe ein präziseres Bild von ihnen, aber was sie gesagt haben, hat micht nicht überrascht, wie auch, wenn ich vorher schon ein paar ihrer Gedanken kannte. Ich war ein wenig enttäuscht.

Aber heute hat sich das geändert. Ich habe einen Talk von Richard Durnell gehört und war – wie sagt man? – begeistert, angefixt, inspiriert. Es mag sein, dass der Talk gar nicht so besonders war, ich bin sicher derjenige, der das am schlechtesten sagen kann, aber in dem Talk fiel ein Gedanke, der für mich genau richtig war. Nicht zu klein, nicht zu gross, genau passend um etwas auszulösen, was sich wohl irgendwie angestaut hatte. Für alle anderen, die diesen Stau nicht haben, ist der Gedanke vielleicht banal, aber hier ist er. Richard hat 5 Jahre lang mit Leuten von Toyota daran gearbeitet ene Fordfabrik auf Leanproduction umzustellen. Er verglich das Lean-Denken mit dem Zen und dem was dort ‘Beginners Mind’ heisst. Er beschrieb, wie sein Mentor, immer wenn er dachte ‘jetzt habe ich es verstanden’, etwas tat oder sagte, was seinem bisherigen Verständnis zuwieder lief. Ganz ähnlich dem Zenmeister, der in unzähligen Geschichten immer wieder den Schüler verblüfft.

Ich hatte mit dem Lean-Ansatz bisher gewisse Schwierigkeiten. Ich fand die einzelnen Ideen spannend, hatte aber dabei die Frage im Hinterkopf: ‘Was ist denn nun Lean’. Nicht dass es da keine Definitionsversuche gibt, aber irgendwie wirken sie alle etwas untersetzt. Nach dem Talk denke ich, es ist gerade das Wesen von Lean, dass es keinen Kern hat. Es ist gerade mein Problem, dass ich immer versuche, die Idee zu strukturieren, in eine tayloristische Form zu bringen. Dem sperrt sich Lean und das ist seine Essenz. Richard schloss seinen Vortrag mit einem Zitat von Konosuke Matsushita (Matsushita Electrics aka Panasonics, Technics).

“We are going to win and the industrial west is going to lose: there’s nothing much you can do about it, because the reasons for your failure are within yourselves. Your firms are built on the Taylor model; even worse, so are your heads….”

Ja das verdammte westliche Tayloristische Hirn.

Das schöne an einem Blog ist, dass man das, was einen zum Platzen bringt, einfach aufschreiben kann und egal ob es einer liest oder nicht, der Druck verringert sich.