Vererbung ist sinnvoll, wenn eine fachlich stabile „ist-ein“-Beziehung besteht und Untertypen den Basistyp zuverlässig ersetzen können. Für wechselnde Regeln und unabhängige Funktionen ist Komposition mit einem gemeinsamen Interface meist die flexiblere Wahl.

Polymorphie sorgt dabei dafür, dass verschiedene konkrete Objekte über denselben Vertrag genutzt werden. Entscheidend sind nicht nur die aktuelle Implementierung, sondern auch Änderungsrate, Testbarkeit und die erwartete Lebensdauer des Moduls.
Wer Architekturberatung, Entwicklertrainings oder Code-Analyse-Tools bewertet, sollte diese Kriterien vor einer langfristigen Pattern-Entscheidung prüfen.
Auf einen Blick
- Vererbung passt zu stabilen Spezialisierungen mit einer klaren „ist-ein“-Beziehung.
- Interfaces und Polymorphie erlauben unterschiedliche Implementierungen hinter einem gemeinsamen Vertrag.
- Komposition und Patterns sind oft besser, wenn Regeln, Algorithmen oder Erweiterungen häufig wechseln.
| Entscheidungskriterium | Vererbung | Interface | Komposition |
|---|---|---|---|
| Typischer Einsatz | Stabile fachliche Spezialisierung | Gemeinsamer Vertrag für unterschiedliche Objekte | Austauschbare Fähigkeiten und Abhängigkeiten |
| Kopplung | Eher eng an die Basisklasse gebunden | Vertrag verbindet, Implementierung bleibt offen | Abhängigkeiten können gezielter getrennt werden |
| Testbarkeit | Kann bei tiefen Hierarchien aufwendiger werden | Implementierungen lassen sich getrennt betrachten | Zusammengesetzte Teile können einzeln geprüft werden |
| Bei häufigen Änderungen | Oft riskanter | Gut für alternative Implementierungen | Meist flexibel für wechselndes Verhalten |
Die kurze Antwort: Gemeinsamen Vertrag zuerst, Vererbung nur bei stabiler Spezialisierung
Beginnen Sie bei erweitertem Verhalten mit der Frage: Welchen gemeinsamen Vertrag brauchen die aufrufenden Teile des Systems? Ein Interface oder eine Basisklasse kann diesen Vertrag darstellen. Vererbung sollte erst folgen, wenn die Spezialisierung fachlich dauerhaft nachvollziehbar bleibt.
Wann ein Interface für polymorphes Verhalten genügt
Ein Interface genügt, wenn mehrere konkrete Objekte dieselbe Aufgabe nach außen erfüllen, intern aber unterschiedlich arbeiten dürfen. Polymorphie ermöglicht dann, alle Varianten einheitlich zu verwenden, ohne dass der aufrufende Code die konkrete Klasse kennen muss. Das ist besonders passend, wenn Implementierungen austauschbar bleiben sollen.
Wann eine abstrakte Basisklasse fachlich sinnvoll bleibt
Eine abstrakte Basisklasse kann sinnvoll sein, wenn Unterklassen tatsächlich gemeinsame Eigenschaften und Verhalten übernehmen sollen. Voraussetzung ist eine belastbare „ist-ein“-Beziehung. Außerdem müssen Untertypen den Basistyp ohne unerwartete Verhaltensänderung ersetzen können. Genau das fordert das Liskovsche Substitutionsprinzip.
Die Drei-Punkte-Regel für die erste Architekturentscheidung
Prüfen Sie erstens, ob die Spezialisierung fachlich stabil ist. Zweitens, ob Varianten nur Verhalten austauschen oder wirklich gemeinsame Grundmerkmale erben. Drittens, ob Änderungen künftig eher neue Regeln als neue Objekttypen betreffen. Bei Unsicherheit ist ein gemeinsamer Vertrag mit Komposition häufig leichter weiterzuentwickeln als eine feste Klassenhierarchie.
Vererbung, Komposition und Interfaces im direkten Vergleich
Kopplung, Erweiterbarkeit und Testbarkeit als Vergleichskriterien
Vererbung koppelt Unterklassen an Entscheidungen der Basisklasse. Änderungen dort können deshalb Seiteneffekte in mehreren Untertypen auslösen. Komposition modelliert dagegen eine „hat-ein“-Beziehung: Eine Klasse erhält Verhalten über zusammengesetzte Objekte. Interfaces definieren vor allem den Vertrag und lassen die konkrete Umsetzung offen. Für wartbaren Code sind klare Verantwortlichkeiten und nachvollziehbare Abhängigkeiten wichtiger als eine besonders elegante Hierarchie auf dem Papier.
Welche Option bei häufig wechselnden Anforderungen besser passt
Ändern sich Geschäftsregeln oder Algorithmen regelmäßig, sollte das variable Verhalten nicht tief in einer Basisklasse versteckt sein. Komposition erlaubt, genau diesen Teil auszutauschen. Ein Interface schafft den gemeinsamen Zugangspunkt. So bleiben neue Varianten möglich, ohne bestehende Unterklassen zwangsläufig verändern zu müssen.
Aufwand im Team: Lesbarkeit, Onboarding und langfristige Wartung
Neue Teammitglieder müssen bei Vererbung oft mehrere Ebenen verfolgen, um eine Methode vollständig zu verstehen. Tiefe Hierarchien erschweren außerdem Tests und die Suche nach Seiteneffekten. Flachere Strukturen mit klaren Verträgen sind für Code-Reviews häufig leichter einzuordnen. Eine professionelle Code-Analyse kann helfen, auffällige Abhängigkeiten und komplexe Klassenbeziehungen sichtbar zu machen.
Entwurfsmuster für austauschbares Verhalten und kontrollierte Erweiterung
Strategy für variable Regeln und Algorithmen
Das Strategy Pattern kapselt austauschbare Algorithmen hinter einem gemeinsamen Interface. Es eignet sich, wenn derselbe fachliche Vorgang mit unterschiedlichen Regeln ausgeführt werden soll. Statt jede Regel als Unterklasse einer wachsenden Hierarchie anzulegen, wird die passende Strategie als zusammengesetztes Objekt verwendet.
Template Method für feste Abläufe mit variablen Schritten
Das Template Method Pattern definiert einen Ablauf in einer Basisklasse. Unterklassen passen einzelne Schritte an. Das kann sinnvoll sein, wenn die Reihenfolge des Prozesses fest bleibt, aber bestimmte Teile bewusst variieren dürfen. Vorsicht ist geboten, wenn Unterklassen immer mehr Sonderfälle benötigen: Dann kann die Basisklasse fragil werden.
Factory Method für entkoppelte Objekterzeugung
Die Factory Method trennt die Erzeugung von Objekten von ihrer späteren Nutzung. Aufrufender Code arbeitet dadurch eher mit dem gemeinsamen Vertrag als mit konkreten Klassen. Das unterstützt Polymorphie und kann verhindern, dass die Objekterzeugung an vielen Stellen verteilt wird.
Typische Architekturfehler und wie sich teures Refactoring vermeiden lässt
Zu tiefe Klassenhierarchien und fragile Basisklassen
Eine tiefe Hierarchie ist ein Warnsignal, wenn Änderungen an der Basisklasse schwer vorhersehbare Folgen in entfernten Unterklassen haben. Auch Tests werden komplexer, wenn benötigtes Verhalten über viele Ebenen verteilt ist. Frühzeitiges Refactoring kann günstiger sein als die dauerhafte Pflege einer Struktur, deren Auswirkungen niemand im Team sicher überblickt.
Typabfragen als Hinweis auf fehlende Polymorphie
Wenn Code wiederholt konkrete Typen unterscheidet, fehlt möglicherweise ein gemeinsamer Vertrag oder die passende polymorphe Operation. Nicht jede Typabfrage ist automatisch falsch. Sie sollte aber Anlass geben zu prüfen, ob Verhalten besser an die jeweiligen Objekte delegiert werden kann.
Wann Komposition eine bestehende Vererbungsstruktur ersetzen sollte

Komposition ist ein naheliegender Kandidat, wenn Unterklassen hauptsächlich einzelne Regeln austauschen, Eigenschaften nur künstlich erben oder Varianten kaum noch zum ursprünglichen Basistyp passen. Ein schrittweiser Umbau reduziert Risiko: Erst den Vertrag klären, dann Verhalten auslagern und vorhandene Aufrufe nach und nach umstellen.
Situationen aus der Praxis: Welche Struktur passt zu welchem Änderungsdruck?
Seltene, fachlich stabile Varianten
Bleiben Varianten langfristig fachlich klar und teilen sie echte Eigenschaften sowie Verhalten, kann Vererbung angemessen sein. Wichtig bleibt, dass jede Unterklasse die Erwartungen an den Basistyp erfüllt. Eine abstrakte Basisklasse kann hier gemeinsame Abläufe bündeln, ohne den Vertrag zu verwässern.
Häufig wechselnde Geschäftsregeln und Plugin-ähnliche Funktionen
Bei wechselnden Regeln bieten sich Strategy und ein gemeinsames Interface an. Plugin-ähnliche Funktionen profitieren ebenfalls davon, dass konkrete Implementierungen getrennt von der Nutzung bleiben. Die Auswahl einer Variante lässt sich so von der eigentlichen Fachlogik entkoppeln.
Legacy-Code: schrittweise modernisieren statt komplett neu schreiben
Legacy-Code muss nicht vollständig ersetzt werden. Beginnen Sie bei besonders schwer testbaren oder häufig geänderten Bereichen. Dokumentieren Sie den bestehenden Vertrag, führen Sie eine klar abgegrenzte Schnittstelle ein und verlagern Sie variable Teile schrittweise in zusammengesetzte Komponenten. Vor einem größeren Umbau kann eine technische Bewertung durch erfahrene Architekturberatung sinnvoll sein.
Auswahlkriterien und Vergleichszusammenfassung für die Architekturentscheidung
Checkliste für Code-Review und technische Bewertung
Prüfen Sie im Code-Review, ob eine echte „ist-ein“-Beziehung vorliegt, Untertypen austauschbar bleiben und die Basisklasse nicht zu viele Sonderfälle steuert. Fragen Sie außerdem, welche Regeln voraussichtlich wechseln, ob Verhalten einzeln testbar ist und ob neue Teammitglieder die Abhängigkeiten zügig nachvollziehen können.
Wann sich Schulung, Code-Analyse oder externe Architekturberatung lohnen kann
Entwicklertrainings können sinnvoll sein, wenn Begriffe wie Polymorphie, Komposition und Entwurfsmuster im Team uneinheitlich verwendet werden. Code-Analyse-Tools helfen bei der strukturierten Prüfung von Abhängigkeiten und auffälligen Klassenbeziehungen. Externe Architekturberatung kann sich anbieten, wenn eine gewachsene Hierarchie mehrere Module betrifft oder ein Refactoring technisch und organisatorisch abgestimmt werden muss.
Entscheidung nach Risiko, Teamgröße und erwarteter Lebensdauer des Moduls
Je länger ein Modul genutzt wird und je mehr Personen daran arbeiten, desto wichtiger sind klare Verträge und geringe Kopplung. Bei hohem Änderungsdruck ist eine flexible Komposition häufig robuster. Bei stabilen fachlichen Spezialisierungen kann Vererbung verständlich und passend bleiben. Prüfen Sie bei Tools, Trainings oder Beratungsangeboten vor allem Analyseumfang, Lernziele und die konkrete Unterstützung für Ihre Codebasis.
Auswahlkriterien und Vergleichszusammenfassung
1. Ist die Spezialisierung fachlich stabil? 2. Können Untertypen den Basistyp ohne Überraschungen ersetzen? 3. Wechseln eher Algorithmen als Objektarten? 4. Lassen sich Komponenten unabhängig testen? 5. Bleibt die Struktur für das Team verständlich? Wenn mehrere Punkte offen bleiben, sollten Sie zuerst Interface und Komposition prüfen. Offizielle Informationen und konkrete Leistungsbedingungen für Code-Analyse, Entwicklertrainings oder Architekturunterstützung finden Sie jeweils auf den entsprechenden Angebotsseiten.
Zum Schluss
Vererbung und Polymorphie sind keine konkurrierenden Selbstzwecke. Sie werden wartbar, wenn der gemeinsame Vertrag klar bleibt und die fachliche Modellierung trägt. Komposition ergänzt diese Werkzeuge überall dort, wo Verhalten austauschbar bleiben soll. Eine kleine, bewusst gewählte Struktur ist meist wertvoller als eine umfangreiche Hierarchie mit vielen Ausnahmen.
Wissenswertes für die Praxis
Interfaces beschreiben den gemeinsamen Zugang zu Verhalten. Komposition setzt auf eine „hat-ein“-Beziehung und kann Abhängigkeiten reduzieren. Strategy passt zu variablen Algorithmen, Template Method zu festen Abläufen mit anpassbaren Schritten und Factory Method zu entkoppelter Objekterzeugung.
Wichtige Hinweise
Welche Struktur konkret geeignet ist, hängt von Programmiersprache, Framework, bestehender Codebasis und erwarteten Änderungen ab. Auch die Verfügbarkeit von Interfaces, abstrakten Klassen, Traits oder Mixins muss im jeweiligen Umfeld geprüft werden. Kosten und Nutzen von Refactoring, Schulungen, Analyse-Tools oder Beratung sind projektbezogen zu bewerten.
Häufig gestellte Fragen
Q1. Wann sollte ich Vererbung statt Komposition verwenden?
A1. Wenn eine stabile „ist-ein“-Beziehung besteht, Unterklassen wirklich gemeinsames Verhalten übernehmen und den Basistyp ohne unerwartete Änderungen ersetzen können. Bei austauschbaren Regeln ist Komposition oft geeigneter.
Q2. Welches Entwurfsmuster eignet sich für austauschbare Geschäftsregeln?
A2. Das Strategy Pattern ist dafür gedacht, unterschiedliche Algorithmen oder Regeln hinter einem gemeinsamen Interface zu kapseln. Die konkrete Strategie kann dadurch von der nutzenden Klasse getrennt bleiben.
Q3. Lohnt sich externe Architekturberatung bei einer komplexen Klassenhierarchie?
A3. Sie kann sinnvoll sein, wenn die Hierarchie schwer nachvollziehbar ist, mehrere Bereiche betrifft oder ein schrittweises Refactoring geplant werden muss. Entscheidend sind Umfang der Codebasis, Änderungsdruck und die Erfahrung des Teams mit der bestehenden Struktur.





