DDD & Co., Teil 2: Semantik statt CRUD

the next big thing  –  1 Kommentare
Anzeige

Die erste Folge hat erklärt, warum CRUD nicht die Antwort auf alle Fragen ist. Der größte Kritikpunkt ist die auf vier Verben begrenzte Semantik: Fachexperten und Anwender denken nicht in CREATE, READ, UPDATE und DELETE. Welche Wörter verwenden sie stattdessen?

Die in der ersten Folge genannte Anwendung, eine auf TodoMVC basierende Aufgabenliste, sieht auf den ersten Blick wie ein Paradebeispiel für den Einsatz von CRUD aus: Es gibt To-dos, und sie lassen sich erzeugen, aktualisieren, löschen und auslesen. Das ist CRUD in Reinkultur.

Wir haben den Ansatz dermaßen verinnerlicht, dass uns kaum mehr auffällt, dass die generische Anwendbarkeit einen hohen Preis hat: fehlende Semantik. Kein Fachexperte oder Anwender denkt in den Verben CREATE, READ, UPDATE und DELETE. Ihnen fehlt jegliche fachliche Bedeutung, weil ihr Kontext eine technische Liste ist: die relationale Datenbanktabelle. Dagegen ist nichts einzuwenden, wenn die Domäne eine SQL-Tabelle ist, im Gespräch mit Fachexperten und Anwendern sind sie aber wenig nützlich.

Schlimmer noch: Sie sind nicht nur nicht nützlich, sie schaden sogar! Wir als Entwickler bilden jeden fachlichen Vorgang unbewusst und automatisch auf CRUD ab. Dabei merken wir nicht, dass wir die Fachsprache gar nicht wirklich verstehen und auf dem Weg viel dazu beitragen, dass Missverständnisse entstehen.

Das ständige Übersetzen ist einer der Gründe, warum das Arbeiten in interdisziplinären Teams so mühsam ist. Alle Beteiligten glauben zwar, über das Gleiche zu sprechen – tatsächlich reden sie aber beständig aneinander vorbei.

Wer das bestreitet, behauptet zugleich, dass eine Sprache, die im Wesentlichen auf Verben verzichtet, genauso ausdrucksstark sei wie eine Sprache, die Aktivitäten facettenreich ausdrücken und darstellen kann. Wie falsch diese Annahme ist, beschreibt Steve Yegge sehr anschaulich und unterhaltsam in seinem Blogeintrag "Execution in the Kingdom of Nouns". Doch welche anderen Möglichkeiten haben wir?

Eine einfache Möglichkeit ist, die Fachexperten und Anwender zu bitten, zu beschreiben, welche Ereignisse in der Anwendung vorkommen können. Verzichtet man dabei auf die vier Verben von CRUD, erhält man auf diese Frage vermutlich Antworten ähnlich wie diese:

  • Eine Aufgabe wurde notiert.
  • Eine andere Aufgabe wurde abgehakt.
  • Wieder eine andere Aufgabe wurde verworfen.
  • Eine Aufgabe wurde erledigt.

Das entspricht viel mehr der Art, über eine Aufgabenliste nachzudenken, wie es jemand machen würde, der kein Entwickler ist. Die Aussagen sind umgangssprachlich, und eventuell erhält man mehrere Formulierungen für das eigentlich (oder vermeintlich) Gleiche. Darüber lässt sich jedoch sprechen, weil die Wortwahl verschiedene Gedanken explizit macht.

Beispielsweise lässt sich nun darüber sprechen, ob "Eine Aufgabe wurde abgehakt." den gleichen Vorgang meint wie "Eine Aufgabe wurde erledigt.". Wenn beide Aussagen tatsächlich den gleichen Vorgang bezeichnen, wäre es hilfreich, sich auf eine Begrifflichkeit zu einigen. Wenn nicht, hat man auf dem Weg zwei unterschiedliche Anwendungskonzepte aufgedeckt, die ansonsten eventuell verborgen geblieben wären – und die erst deutlich später, nämlich in der implementierten Anwendung, als falsch aufgefallen wären.

Das Ziel des Vorgehens ist, sich auf eine allgegenwärtige Sprache zu einigen, damit alle Teammitglieder einander verstehen und klar ist, worüber gesprochen wird. Die Sprache gilt aber nur in einem begrenzten Kontext, sie ist nicht universell. Das liegt daran, dass Aufgabenlisten unterschiedliche Zwecke erfüllen können, was sich in der Wortwahl niederschlägt.

Deshalb ist es wichtig, den Kontext zu kennen, wenn man sich mit jemandem in einer Fachsprache ausdrücken will. Aus ebendiesem Grund spricht man auch von einem begrenzten Kontext (englisch: Bounded Context), innerhalb dessen Grenzen die allgegenwärtige Sprache (englisch: Ubiquitous Language) gilt.

Wie sieht nun diese Sprache für die vorliegende Aufgabenliste aus? Dazu muss man die Intention der Anwender hinterfragen und verstehen, warum Vorgänge durchgeführt werden. Beispielsweise ist die Intention der Anwender, eine noch zu erledigende Aufgabe nicht zu vergessen. Deshalb wird die Aufgabe notiert.

Im Gegensatz dazu ist es nicht die Intention der Anwender, dem technischen Konstrukt einer Liste einen Eintrag hinzuzufügen (CREATE). Es spielt noch nicht einmal eine Rolle, dass es sich aus technischer Sicht überhaupt um eine Liste handelt – für die Intention der Anwender könnte es genauso gut ein Grid sein, das Kacheln enthält.

Die übrigen Verben sind rasch gefunden: Eine Aufgabe kann nachbearbeitet werden, sie kann abgehakt werden, und sie kann wieder aufgegriffen werden, wenn sie fälschlicherweise abgehakt wurde. Eine Aufgabe kann zudem verworfen werden, wenn sie sich erübrigt hat. Abgehakte Aufgaben können außerdem archiviert werden, wenn sie nicht mehr präsent sein müssen.

Es fällt auf, dass alle diese Verben in der Vergangenheitsform stehen. Der Grund dafür ist, dass sie für die Domäne der Aufgabenliste relevante fachliche Ereignisse (englisch: Domain Events) sind. Außerdem fällt auf, dass mehr als drei Verben (CREATE, UPDATE, DELETE) gefunden wurden, die Semantik selbst einer Aufgabenliste scheint also doch komplexer zu sein, als aus Datenbanksicht erwartet.

Um die Konsistenz zur englischen Benutzeroberfläche der Anwendung herzustellen, empfiehlt es sich, die Verben noch auf Englisch zu übersetzen. Generell kann dieser Schritt jedoch entfallen, und die Ereignisse sollten in jener Sprache formuliert werden, in welcher der Kern der Geschäftslogik beschrieben wird. Auf dem Weg erhält man nun folgende Verben:

  • noted
  • edited
  • ticked off
  • resumed
  • discarded
  • archived

Damit ist der erste Schritt für die Modellierung einer Anwendung mit Domain-Driven Design gemacht. Auch wenn das Ergebnis vielleicht noch wenig Begeisterung hervorruft, ist doch schon etwas sehr Wesentliches gewonnen: Es existiert eine gemeinsame fachliche Sprache, deren Bedeutung nicht einfach nur en passant entstanden ist.

Genau das ist letztlich das Ziel von DDD: Das Verbessern der Kommunikation in interdisziplinären Teams, damit schlussendlich bessere Software entsteht, die tatsächliche Probleme löst und die Bedürfnisse und Wünsche der Anwender erfüllt. Der einzige Weg, um dieses Ziel zu erreichen, ist miteinander zu reden – und zwar so früh wie möglich.

tl;dr: Das Ziel von Domain-Driven Design ist eine bessere Kommunikation in interdisziplinären Teams. Dazu dient das Definieren einer allgegenwärtigen Sprache in einem begrenzten Kontext. Der wichtigste Baustein dieser Sprache sind fachliche Ereignisse, die Vorgänge in der Domäne beschreiben.

Anzeige