Simyl
simylflow
Kursübersicht
Modul 2: Technische Praktiken
Lektion 5 von 5
14 Min.

Einfaches Design

Baue das Einfachste, das funktioniert. Widerstehe dem Drang, zu viel zu entwickeln.

1Das Einfachste, das Funktioniert

XP hat ein Mantra: Mach das Einfachste, das möglicherweise funktionieren könnte.

Das bedeutet nicht, faul zu sein oder unsauberen Code zu schreiben. Einfacher Code ist oft schwerer zu schreiben als komplexer Code. Es erfordert:

  • Das Problem tiefgehend zu verstehen
  • Dem Drang zu widerstehen, zu generalisieren
  • „Nein" zu Spekulationen zu sagen
  • Darauf zu vertrauen, dass du Dinge später ändern kannst

Einfacher Code ist:

  • Leicht zu verstehen
  • Leicht zu ändern
  • Leicht zu testen
  • Gerade genug für aktuelle Anforderungen

Komplexer Code ist:

  • Schwer zu verstehen
  • Riskant zu ändern
  • Schwer zu testen
  • Für imaginäre zukünftige Anforderungen gebaut, die vielleicht nie kommen

Einfach ist Schwer

„Ich hätte einen kürzeren Brief geschrieben, aber ich hatte nicht die Zeit." —Blaise Pascal. Einfacher Code erfordert mehr Nachdenken, nicht weniger.

2YAGNI: You Aren't Gonna Need It

YAGNI ist das Prinzip, dass du nur das bauen solltest, was du gerade jetzt brauchst.

Füge nicht hinzu:

  • Features, weil sie „vielleicht nützlich sein könnten"
  • Konfigurationsoptionen, weil Nutzer sie „vielleicht wollen könnten"
  • Erweiterungspunkte, weil der Code sie „vielleicht brauchen könnte"
  • Abstraktionen für hypothetische zukünftige Anforderungen

Warum? Weil:

  • Du dich meistens irrst, was du brauchen wirst
  • Ungenutzter Code trotzdem Wartungskosten verursacht
  • Jede Abstraktion einen Preis in Komplexität hat
  • Das Bauen für die Zukunft das Liefern für heute verzögert

Die XP-Wette: Wenn du später etwas brauchst, kannst du es später hinzufügen. Mit TDD, Refactoring und CI ist Änderung günstig. Also zahle nicht für die Zukunft, bevor du musst.

Das ist eine radikale Idee. Traditionelles Software Engineering sagt, antizipiere Änderungen und entwirf für Flexibilität. XP sagt, warte, bis du es tatsächlich brauchst.

Gutes YAGNI

Das Team muss E-Mails versenden. Sie implementieren das Versenden über SMTP. Später brauchen sie SendGrid. Sie refaktorieren. Gesamtkosten: weniger als eine steckbare E-Mail-Abstraktion von Anfang an zu bauen.

YAGNI Verletzen

Das Team muss E-Mails versenden. Sie bauen ein generisches 'MessageProvider'-Interface mit steckbaren 'MessageTransport'- und 'MessageFormatter'-Abstraktionen. Sie nutzen nur jemals SMTP mit einem Format. Die Abstraktionen verlangsamen jede Änderung.

3Die Vier Regeln des Einfachen Designs

Kent Beck definierte einfaches Design als Code, der:

1. Alle Tests besteht Der Code funktioniert. Das ist nicht verhandelbar. Ein schönes Design, das nicht funktioniert, ist wertlos.

2. Absicht offenbart Der Code ist leicht zu verstehen. Gute Namen, klare Struktur, lesbare Organisation. Jemand Neues kann ihn aufgreifen und verstehen, was er tut.

3. Keine Duplikation hat (DRY) Jedes Stück Wissen ist einmal und nur einmal ausgedrückt. Duplikation erzeugt Wartungslast und Fehlerrisiko.

4. Die wenigsten Elemente hat Keine zusätzlichen Klassen, Methoden, Variablen oder Abstraktionen. Alles, was existiert, hat einen Grund zu existieren.

Die Regeln sind in Prioritätsreihenfolge. Tests zu bestehen übertrifft alles. Aber sobald Tests bestehen, bevorzuge Klarheit über DRYness. Und füge nur Elemente hinzu, die den ersten drei Regeln dienen.

4Inkrementelles Design

Einfaches Design bedeutet nicht kein Design. Es bedeutet inkrementelles Design – das Design entwickelt sich, während du lernst.

Der Prozess:

  1. Beginne mit der einfachsten Implementierung, die funktioniert
  2. Während du Features hinzufügst, bemerke Reibung (das wird umständlich)
  3. Refaktoriere, um die Reibung zu beheben
  4. Das Design entsteht aus echten Bedürfnissen, nicht aus Spekulation

Deshalb betont XP Refactoring so stark. Wenn du den Code nicht sicher ändern kannst, kannst du kein inkrementelles Design machen. Du steckst mit dem fest, was du zuerst gebaut hast.

Big Up-Front Design (BUFD) scheitert, weil:

  • Du am Anfang nicht genug weißt
  • Anforderungen sich ändern
  • Designs den Kontakt mit der Realität nicht überleben
  • Du für Komplexität zahlst, die du nie nutzt

Inkrementelles Design gelingt, weil:

  • Du basierend auf echten Bedürfnissen entwirfst
  • Das Design sich mit dem Verständnis entwickelt
  • Du nie für das zahlst, was du nicht nutzt
  • Refactoring das Design sauber hält

Wenn du den Drang verspürst, eine Abstraktion hinzuzufügen, frage: „Brauche ich das jetzt, oder rate ich?" Wenn du rätst, warte.

5Wann Komplexität Gerechtfertigt Ist

Einfaches Design bedeutet nicht, jede Komplexität zu vermeiden. Manchmal ist Komplexität notwendig.

Füge Komplexität hinzu, wenn:

  • Tests sie erfordern (lass es bestehen)
  • Klarheit sie erfordert (offenbare Absicht)
  • Das Entfernen von Duplikation sie erfordert (DRY)
  • Aktuelle, echte Anforderungen sie brauchen

Füge keine Komplexität hinzu für:

  • „Was-wäre-wenn?"-Szenarien
  • Mögliche zukünftige Features
  • Frameworks, die du vielleicht brauchen könntest
  • Den Code „flexibler" zu machen

Der Unterschied liegt zwischen wesentlicher Komplexität (dem Problem inhärent) und zufälliger Komplexität (durch deine Lösung eingeführt). XP minimiert zufällige Komplexität, indem es sich weigert, für imaginäre Anforderungen zu bauen.

Wenn du eine Abstraktion brauchst, lass sie aus dem Entfernen von Duplikation entstehen. Die „Regel der Drei" ist hilfreich: abstrahiere nicht, bis du dasselbe Muster dreimal siehst. Bis dahin verstehst du die tatsächlichen Variationen, nicht die imaginierten.

Wichtige Erkenntnisse
  • Einfacher Code ist schwerer zu schreiben, aber leichter zu ändern
  • YAGNI: baue nicht für Anforderungen, die du noch nicht hast
  • Die vier Regeln: besteht Tests, offenbart Absicht, keine Duplikation, wenigste Elemente
  • Lass Design inkrementell durch Refactoring entstehen
  • Füge Komplexität hinzu, wenn Tests, Klarheit oder DRY sie erfordern – nicht für Spekulation
Häufige Fehler, die es zu vermeiden gilt
  • Einfach mit simplistisch verwechseln (einfach ist elegant, nicht grob)
  • Abstraktionen bauen, bevor du sie brauchst
  • Annehmen, dass du weißt, was zukünftige Anforderungen sein werden
  • Refactoring überspringen, was Design-Evolution verhindert

Praxisübungen