Die sieben Grundprinzipien der OOP [1]
- Prinzip einer einzigen Verantwortung
- Trennung der Anliegen
- Wiederholungen vermeiden
- Offen für Erweiterungen, geschlossen für Änderung
- Trennung der Schnittstelle von der Implementierung
- Umkehr der Abhängigkeiten
- Mach es testbar
Oft muss ein- und dasselbe Modul in verschiedenen Umgebungen eingesetzt werden, in verschiedenen Programmen oder im gleichen Programm unter verschiedenen Betriebssystemen.
Das naheliegende Verfahren ist es, dieses Modul zu kopieren und dann an die neue Umgebung anzupassen.
Dieses Verfahren birgt aber einige Risiken. Wenn sich die Anforderungen an dieses Modul ändern, müssen alle Kopien entsprechend verändert werden. Dabei kann es zu Inkonsistenzen und entsprechenden Fehlern kommen.
Ein Modul soll für Erweiterungen offen sein, aber nicht indem das Modul geändert wird, sondern indem es mit Erweiterungsmodulen gekoppelt wird, die entsprechend angepasst werden können.
"Das Modul soll also definierte Erweiterungspunkte bieten, an die sich die Erweiterungsmodule anknüpfen lassen." [1]
Open-Closed-Principle
Dieser Text wurde von ChatGPT erstellt und von mir dann leicht überarbeitet.
Das Open-Closed-Principle (OCP) gehört zu den grundlegenden Entwurfsprinzipien der objektorientierten Programmierung. Es beschreibt eine zentrale Zielsetzung beim Entwurf von Klassen und Modulen:
- Offen für Erweiterung: Das Verhalten eines Moduls soll sich erweitern lassen, zum Beispiel durch neue Klassen oder neue Implementierungen.
- Geschlossen für Änderung: Der bestehende Quelltext des Moduls soll dabei möglichst unverändert bleiben.
Ziel dieses Prinzips ist es, Programme so zu strukturieren, dass neue Anforderungen nicht zu umfangreichen Änderungen am bestehenden Code führen. Änderungen am bestehenden Quelltext sind immer potenziell riskant, da sie neue Fehler einführen können oder bestehende Funktionalität unbeabsichtigt beeinflussen.
Ein häufiger Entwurfsfehler besteht darin, vorhandene Klassen zu kopieren und leicht zu verändern, wenn eine neue Variante benötigt wird. Solche Code-Duplikate sind schwer wartbar, da spätere Korrekturen oder Erweiterungen in allen Kopien nachvollzogen werden müssen. Dieses Problem wird auch im Zusammenhang mit dem Prinzip "Wiederholungen vermeiden" thematisiert.
Stattdessen sollten Klassen so entworfen werden, dass neue Funktionalität durch Vererbung, Polymorphie oder durch das Zusammenspiel mehrerer Klassen ergänzt werden kann, ohne bestehende Klassen verändern zu müssen.
Ein einfaches Beispiel
Das folgende Beispiel ist bewusst einfach gehalten und kommt ohne Interfaces aus. Es soll lediglich die Grundidee des Open-Closed-Principles verdeutlichen.
public class Begruesser
{
public void begruessen()
{
System.out.println("Hallo!");
}
}
Nun werden zwei neue Varianten durch Unterklassen ergänzt:
public class EnglischerBegruesser extends Begruesser
{
public void begruessen()
{
System.out.println("Hello!");
}
}
public class SpanischerBegruesser extends Begruesser
{
public void begruessen()
{
System.out.println("¡Hola!");
}
}
Verwendung im Programm:
Begruesser b1 = new Begruesser(); b1.begruessen(); // Hallo! Begruesser b2 = new EnglischerBegruesser(); b2.begruessen(); // Hello! Begruesser b3 = new SpanischerBegruesser(); b3.begruessen(); // ¡Hola!
Die ursprüngliche Klasse Begruesser musste nicht verändert werden. Neue Varianten entstehen ausschließlich durch Erweiterung. Damit erfüllt dieses Beispiel das Open-Closed-Principle in seiner Grundform.
Beispiel: Bibliotheks-Projekt
Ein deutlich realistischeres Beispiel findet sich im Bibliotheks-Projekt aus den Folgen 7.3 und 7.4 des OOP-Kurses. Dort existiert die Oberklasse Buch mit der Methode zeige(). Diese Methode wird von verschiedenen Unterklassen überschrieben, etwa Roman, Sachbuch oder Hoerbuch.
Die Klasse Buchliste arbeitet ausschließlich mit Referenzen vom Typ Buch:
for (Buch b : buchliste)
{
b.zeige();
}
Wird nun eine neue Unterklasse wie Hoerbuch ergänzt, muss der Quelltext der Klasse Buchliste nicht verändert werden. Die neue Klasse fügt sich automatisch in das bestehende System ein, da sie den gleichen Methodenvertrag erfüllt.
Das Projekt ist damit offen für Erweiterungen (neue Bucharten), aber geschlossen gegenüber Änderungen an der bestehenden Logik zur Verarbeitung und Ausgabe der Bücher.
Fazit
Das Open-Closed-Principle ist kein Selbstzweck, sondern ein Leitprinzip für wartbaren und erweiterbaren Code. Es hilft, Programme so zu strukturieren, dass neue Anforderungen durch Erweiterung bestehender Strukturen umgesetzt werden können, ohne bewährten Code ständig anpassen zu müssen.
Besonders in Kombination mit Vererbung und Polymorphie zeigt sich der praktische Nutzen dieses Prinzips sehr deutlich.
Quellen:
- Lahres et al.: Objektorientierte Programmierung, Rheinwerk Computing 2021.
- Barnes, Kölling: Java lernen mit BlueJ - Objects first. Pearson-Verlag 2019.
- Ullenboom: Java ist auch eine Insel, Rheinwerk Computing 2023.