Deep Modules
Details
- Auch bekannt als
-
Module Depth, Deep Classes
Kernkonzepte:
- Modultiefe
-
Das Verhältnis von Nutzen (bereitgestellte Funktionalität) zu Kosten (Schnittstellenkomplexität). Ein tiefes Modul bietet mächtige Funktionalität hinter einer kleinen, stabilen Schnittstelle; ein flaches Modul exponiert nahezu so viel Komplexität, wie es enthält.
- Flaches Modul
-
Ein Modul, dessen öffentliche Schnittstelle fast so komplex ist wie seine Implementierung. Flache Module verschieben die Komplexitätslast auf den Aufrufer, anstatt sie zu verbergen — Schnittstellenkosten ohne proportionalen Abstraktionsgewinn.
- Schnittstelle als Kosten
-
Jedes Element einer öffentlichen API — Parameter, Typen, Konfigurationsoptionen, Seiteneffekte — ist kognitive Kosten, die jeder Aufrufer zahlen muss. Tiefe Module minimieren diese Kosten und maximieren gleichzeitig den Nutzen.
- Information Hiding
-
Module sollen Entwurfsentscheidungen kapseln, die sich wahrscheinlich ändern werden: Datenstrukturen, Algorithmen, Dateiformate, Protokolle. Diese Entscheidungen bleiben für Aufrufer unsichtbar, sodass die Schnittstelle stabil bleibt, auch wenn sich die Implementierung weiterentwickelt.
- Classitis
-
Outerhousts Begriff für das Anti-Pattern, ein System in viele winzige, flache Klassen zu zerlegen. Jede Klasse fügt der kollektiven kognitiven Last ihre eigene Schnittstelle hinzu, ohne die Gesamtimplementierungskomplexität zu reduzieren.
- Andere Schicht, andere Abstraktion
-
Jede Architekturschicht soll Abstraktionen anbieten, die sich von der darunterliegenden Schicht bedeutsam unterscheiden. Eine Schicht, die lediglich Aufrufe der darunter liegenden Schicht umbenennt, ohne Substanz hinzuzufügen, ist ein flacher Durchreicher — ein Zeichen schlechten Designs.
- Schlüsselvertreter
-
John Ousterhout ("A Philosophy of Software Design", 2nd ed., Yaknyam Press, 2021; 1. Auflage 2018 — Kapitel 4: „Modules Should Be Deep")
Wann zu verwenden:
-
Beim Entwerfen der öffentlichen API eines Moduls — prüfen, ob die Schnittstelle einfacher ist als die dahinterliegende Implementierung
-
Beim Überprüfen einer vorgeschlagenen Klassenzerlegung, ob sie Komplexität reduziert oder nur umverteilt
-
Beim Identifizieren von Pass-Through-Methoden und Wrapper-Ketten, die Schnittstellenkosten hinzufügen, ohne Details zu verbergen
-
Bei der Anweisung an ein LLM, APIs oder Klassengrenzen mit minimaler sichtbarer Oberfläche zu entwerfen
-
Bei der Wahl zwischen einer allgemeinen und einer spezifischen API — die tiefere, allgemeinere Option bevorzugen
Verwandte Anker:
Kritik:
-
Andrey Lebedev, "Not My Philosophy of Software Design" (Medium) — argumentiert, dass das Erzwingen von Tiefe in einer einzelnen Klasse das Single Responsibility Principle verletzt; das Java-I/O-Beispiel vermischt Dateilesen und Pufferung — zwei genuine separate Belange; tiefe Allzweck-Klassen widersetzen sich zudem der Komposition und erzeugen Kopplung, die der Domain-Driven-Design-Praxis widerspricht
-
"Modules Should Be Deep!" (Software Engineering: A Modern Approach) — fügt Nuancen hinzu:
String.isEmpty()bietet semantische Klarheit und sichere Kapselung trotz trivialer Implementierung und stellt damit eine rein quantitative Interpretation von Tiefe in Frage; Bertrand Meyers Eisberg-Metapher — kleine sichtbare Spitze über großem versenktem Sockel — wird als ergänzende Sichtweise angeführt