Deep Modules ist John Ousterhouts Entwurfsprinzip aus A Philosophy of Software Design: Ein Modul soll viel Funktionalität hinter einer kleinen, stabilen Schnittstelle bieten. Weil jedes Schnittstellenelement Kosten für den Aufrufer bedeutet, verbergen tiefe Module Entwurfsentscheidungen, die sich wahrscheinlich ändern. Flache Module, deren Schnittstelle fast so komplex ist wie ihre Implementierung, verschieben die Komplexität auf den Aufrufer.
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