Kannst du das nicht später entscheiden?
Guter Code entsteht, wenn Entscheidungen dort fallen, wo sie trivial sind.
Vor einiger Zeit hatte ich einen Kollegen, der mir, wenn ich ihn um Hilfe bittend auf meinen Code habe schauen lassen, regelmäßig eine einfache Frage gestellt hat: »Kannst du das nicht später entscheiden?«
Dinge später zu entscheiden. Dinge so spät wie möglich zu entscheiden, ist eines von sieben Prinzipien von Lean Software Development. Einer Methode, die darauf abzielt Verschwendung zu minimieren und den Wert für Kund:innen zu maximieren. Dieser Ansatz ist heute ein integraler Bestandteil der agilen Softwareentwicklung: Defer Commitment
Komplex statt kompliziert
Was hat mein Kollege in meinem Code gesehen? Nun, ich hatte eine komplizierte Logik auf eine komplexe Weise implementiert.
Ich hatte eine lange Methode geschrieben, in der mehrere Objekte zusammenarbeiten mussten. Dazu kamen Filter, Sonderfälle und Berechnungen. Der Code war gewachsen und ich brauchte Hilfe. Ich hatte mich in meinem Code verlaufen und hoffte ein Paar frische Augen könnten sehen, wo ich den nächsten Sonderfall berücksichtigen sollte.
»Kannst du das nicht später entscheiden?«
Damals konnte ich mit der Frage nicht direkt etwas anfangen. Heute halte ich sie für eine der wertvollsten, die man sich stellen kann.
Was mit »später entscheiden« gemeint ist
Er meinte selbstverständlich nicht, dass man Entscheidungen aufschieben oder sich drücken soll… Er meinte: Triff Entscheidungen dort, wo es einfach ist sie zu treffen. Dort, wo du erwarten würdest, dass sie getroffen werden.
In der Praxis heißt das: Verlagere Berechnungen, Filter, Validierungen etc. so tief wie möglich in deine Aggregate, Domänenobjekte oder ValueObjects.
Ein Beispiel
Stell dir ein Lager vor:
- Es gibt mehrere Regale.
- In den Regalen stehen Kisten.
- In den Kisten liegen Produkte.
- Produkte haben ein Volumen.
- Die Kisten und Regale haben eine maximale Kapazität.
Und nun möchtest du herausfinden ob das gesamte Lager, für die Produkte die darin gelagert werden, ausreichend dimensioniert ist.
Klingt einfach? Kann aber komplex werden, wenn man die falsche Ebene entscheiden lässt.
Ein ungünstiger Ansatz: Das Lager entscheidet alles
Du könntest es so machen:
- Das Lager greift in jedes Regal hinein
- holt sich alle Kisten
- schaut in jede Kiste
- zählt alle Produkte
- summiert alle Volumina
- prüft, ob die Kiste überfüllt ist
- ob das Regal überfüllt ist
- und rechnet am Ende alles zusammen
Das Lager müsste also:
- die interne Struktur jedes Regals kennen
- wissen, wo die Kisten darin stehen
- wissen, dass in den Kisten Produkte sind
- wissen, wie deren Volumen berechnet wird
- verstehen, was überfüllt bedeutet…
…und mit diesen Informationen eine Berechnung orchestrieren, deren einzelne Bestandteile höchstwahrscheinlich nicht wiederverwendbar sind.
Was daran problematisch ist?
Ungeachtet dessen, dass es ein grober Verstoß gegen das Information Hiding Principle ist, hat das Lager zu viel Verantwortung. Sozusagen ein Anemic Domain Model im Domain Model. Eine große Berechnung auf Ebene des Lagers zu orchestrieren droht in Komplexität zu enden.
Der richtige Ansatz: Jede Ebene entscheidet selbst
Und jetzt ändern wir die Perspektive. Was wäre, wenn jede Ebene nur über das entscheidet, was sie wirklich kennt? So entsteht eine Logikkette an der wir uns entlanghangeln können und deren Einzelteile in den Kopf passen.
Ebene 0 ↓: Das Lager fragt die Regale: »Bist du voll? Bist du stabil? Passt alles rein?«
Ebene 1 ↓ : Regale fragen intern ihre Kisten.
Ebene 2 ↓ : Kisten fragen intern ihre Produkte.
Ebene 3 - : Produkte wissen ihr eigenes Volumen.
Ebene 2 ↑ : Kisten wissen wie viel sie insgesamt aufnehmen können, wie voll sie sind oder ob sie überfüllt sind.
Ebene 1 ↑ : Regale wissen wie viele Kisten sie tragen können und ob sie überlastet sind.
Ebene 0 ↑ : Das Lager sammelt die Ergebnisse der Regale und kann einen Status zurückgeben.
Fazit
Klassisch wird Defer Commitment eher auf User-Story- bzw. Planungs-Ebene diskutiert. Aber das Prinzip wirkt genauso stark auf Code-Ebene. Und dort wird es erstaunlich oft übersehen!
Wenn man die Entscheidung nach unten verlagert, passiert etwas Magisches: Jede Entscheidung wird lokal, klar, klein und dadurch fast schon trivial.
Und genau das meinte mein Kollege mit seinem Satz, den ich nie vergessen werde:
»Kannst du das nicht später entscheiden?«
