Fakt ist: Softwaresysteme ändern sich regelmäßig! Ständig werden neue Anforderungen an die Software gestellt, bereits bestehende Anforderungen werden geändert. Dieses kann durch den Kunden bzw. Auftraggeber getrieben sein, aber auch technologischer Fortschritt oder andere sich ändernde Randbedingungen können derartige Veränderungen erforderlich machen.
„All systems change during their life cycles. This must be borne in mind when developing systems expected to last longer than the first version.“
(Ivar Jacobson, 1992)
Das Open-Closed Principle wurde erstmals von dem französischen Informatiker Betrand Meyer, Entwickler der objektorientierten Programmiersprache Eiffel und heute Professor für Software Engineering an der ETH in Zürich, in seinem Buch Object Oriented Software Construction (Prentice Hall, 1988) vorgestellt. Es lautet:
Software-Einheiten (Module, Klassen, Funktionen, etc.) sollten offen für Erweiterungen, aber geschlossen für Modifikationen sein.
Vielleicht kennt der eine oder andere Leser folgendes Phänomen: eine Änderung oder Erweiterung einer Software führt zu einer wahren Kaskade an weiteren Änderungen, oder es treten unerwünschte Seiteneffekte auf. Das Open-Closed-Principle soll dafür sorgen, das bereits bestehendes und korrektes Verhalten von Software zwar erweitert werden kann („…offen für Erweiterungen…“), diese Erweiterungen aber nicht zu unerwünschten Seiteneffekten führen bzw. bereits bestehendes Verhalten nicht verändert wird („…geschlossen für Modifikationen…“). Das Open-Closed Principle besagt also, das ein (ideales!) Softwaresystem dadurch gut erweiterbar und veränderbar wird, indem man das System aus Modulen aufbaut, welche sich niemals verändern dürfen. Wenn sich die Anforderungen an das System ändern dann werden diese erfüllt, indem man neuen Code hinzufügt, und nicht dadurch, das man bestehenden, funktionierenden Code ändert. In der objekt-orientierten Software-Entwicklung können wir daher das Open-Closed Principle auch wie folgt ausdrücken:
Software-Einheiten (Module, Klassen, Funktionen, etc.) sollten erweitert werden, indem man ihnen durch Nutzung von objekt-orientierten Mechanismen wie Vererbung und Polymorphie neues Verhalten hinzufügt, anstatt diese Module intern zu verändern.
Zuerst möchte ich ein C++ Code-Beispiel zeigen, welches eine Verletzung des Open-Closed Principles darstellt. Nehmen wir mal an wir haben ein Softwaresystem, welches verschiedene Geräte für die Weitverkehrskommunikation nutzt:
Natürlich ist dieses Programmdesign nicht grundsätzlich falsch; es dürfte das tun, was der Entwickler beabsichtigt hat. Allerdings tendieren derartige Entwürfe dazu, mit switch-case- oder if-else-statements sprichwörtlich durchsetzt zu sein, also: zahlreiche Fallentscheidungen, die den Programmverlauf in Abhängigkeit vom - in diesem Fall - verwendeten Gerät zur Weitverkehrskommunikation steuern.
Das Problem ist: jedes Mal, wenn entweder ein neues Gerät hinzugefügt werden muss (z.B. ein SatComNetworkDevice), oder wenn an den bestehenden Geräten etwas modifiziert werden soll, muss der gesamte Code nach jeglichem Vorkommen von diesen Fallentscheidungen durchforstet werden, was ein erhebliches Fehlerpotenzial in sich birgt. Somit ist dieses Modul nicht geschlossen für Veränderungen.
Hier nun das gleiche Programm nach einem Redesign unter Beachtung des OCP:
Der Vorteil dieses Designs ist offensichtlich: Müssen neue WAN devices hinzugefügt werden, so kann dieses erfolgen ohne dass bereits existierende WAN devices verändert werden müssen. Damit sinkt das Risiko, das sich in bereits existierendem Code Fehler einschleichen, denn diesen Code kann man unangetastet lassen. Muss der Entwickler - z.B. auf Grund einer sich ändernden Spezifikation - ein WAN device ändern, so geschieht dieses ebenfalls sehr lokal und damit nebenwirkungsfrei.
Heuristiken und Konventionen
Das Open-Closed Principle ist eine wesentliche Grundlage für viele Designheuristiken, die im OOD empfohlen sind:
- Alle Attribute einer Klasse sollten mit der Sichtbarkeit
privatedeklariert werden. - Vermeide globale Variablen.
- Vorsicht vor falscher Verwendung von runtime type identification (RTTI), da es geeignet ist, das OCP auszuhebeln.




