Das Dreieck der Abstraktionen
Wir als Developer suchen immer nach der perfekten Abstraktion. Aber diese existiert schlichtweg nicht. Es geht immer um Kompromisse. Die Einfachheit der Schnittstelle, die Wiederverwendbarkeit der Abstraktion und der Scope der Abstraktion sind die verschiedenen Ziele, die das Dreieck der Abstraktionen aufspannen. Und wie es bei Dreiecken im Softwaredesign so ist, kann man immer nur zwei der drei Faktoren gleichzeitig erfüllen.
iJS in München
Letzte Woche fand die International JavaScript Conference in München statt. Ich hatte die Ehre, nicht nur einen, sondern zwei Vorträge zu halten. Einer handelte von den Regeln von React und wie sie sich mit den neuen Concurrent Features verändert haben, der andere drehte sich um Softwareabstraktionen und wie man die richtige findet. Während der Vorbereitung dachte ich viel darüber nach, was eine gute Abstraktion ausmacht. So stellte ich mir die perfekte Abstraktion vor: eine mit einer super einfachen Schnittstelle, die sehr leicht zu verstehen und zu nutzen ist, einem sehr großen Umfang, sodass sie viele Komplexitäten abdeckt, und einer hohen Wiederverwendbarkeit für unterschiedliche Anwendungsfälle. So entstand das Dreieck der Abstraktionen.
Beispiele der Extremen
Nachdem ich keine Abstraktion finden konnte, die alle drei Punkte abdeckt, war es recht einfach, Beispiele für Kombinationen aus jeweils zwei der drei Dimensionen zu finden.
- Großer Umfang und Wiederverwendbarkeit: Ein Data-Grid-Komponente – Viele Konfigurationsmöglichkeiten, sehr großer Funktionsumfang, viele Komplexitäten, die vor einem verborgen bleiben, aber eine riesige, oft schwer verständliche Schnittstelle.
- Hohe Wiederverwendbarkeit, einfache Schnittstelle: Eine Icon-Komponente – Kann bereits sehr nützlich sein, wenn sie nur eine einzige Konfigurationsoption hat: das Icon, das angezeigt werden soll. Kann in unterschiedlichsten Kontexten verwendet werden, in denen ein Icon angezeigt werden muss. Es könnte hunderte Instanzen der Icon-Komponente in der gesamten App geben.
- Einfache Schnittstelle und großer Umfang: Der App-Komponente oder die Main-Funktion – Meistens keine Konfigurationsmöglichkeiten. Ein Funktionsaufruf, und plötzlich hat man Excel Online, Figma oder Google Maps! Aber eine
<GoogleMaps />
-Komponente wird einem wahrscheinlich nicht helfen, einen weiteren Figma-Konkurrenten zu entwickeln, sodass die Wiederverwendbarkeit gering ist.
Welche Position im Dreieck ist also die beste? Wie immer kommt es darauf an. Alle Beispiele sind völlig in Ordnung, um sie in einer App zu haben. Je nach Anwendungsfall müssen wir Entwickler*innen Entscheidungen treffen.
Eine einfache Entscheidung mit drei Optionen
Das bedeutet, wenn du ein neues Ticket bekommst, das den Umfang eines Moduls erweitern soll (wie cool wäre es, wenn wir öfter Tickets bekämen, die den Umfang reduzieren?), hast du drei Möglichkeiten:
Umfang erhöhen und Wiederverwendbarkeit/Flexibilität verringern:
Vielleicht ist das völlig in Ordnung, weil du diese Funktion nicht flexibel anpassen musst und durch das Verschieben dieses Features in die Komponente alle Aufrufstellen plötzlich viel leistungsfähiger werden.
Umfang erhöhen und Wiederverwendbarkeit durch zusätzliche Konfigurationsmöglichkeiten beibehalten:
Könnte auch sinnvoll sein. Vielleicht entwickelst du eine Bibliothek und ein neuer Anwendungsfall ist aufgetaucht, den du bei der ursprünglichen Gestaltung einfach vergessen hast. Jetzt musst kannst du die Schnittstelle erweitern, indem du eine weitere Option hinzufügen und machst sie dadurch natürlich etwas komplizierter.
Umfang nicht erhöhen:
Zum Glück ist das auch eine Option. Anstatt den Umfang einer Abstraktion immer weiter zu vergrößern, könntest du auch „nein“ sagen, weil es vielleicht an der Zeit ist, eine separate Funktion/ein separates Modul/eine separate Komponente zu erstellen, um diesen neuen Anwendungsfall zu übernehmen, sodass keine bestehenden Module angefasst werden müssen.
Kein Allheilmittel
Wie immer im Softwaredesign gibt es keine beste Option. Es geht immer um Trade-Offs. Wenn du also darüber nachdenkst, einer Bibliothek ein Feature hinzuzufügen, hoffe ich, dass du an das Dreieck der Abstraktionen denkst, um bewusst zu entscheiden, in welche Richtung du gehen möchtest.