Das Open/Closed Principle, definiert von Bertrand Meyer, besagt:
„Ein Softwareartefakt sollte erweitert, statt modifiziert werden.“
Dies ermöglicht einfache Erweiterungen, ohne umfangreiche Änderungen am bestehenden Quellcode vornehmen zu müssen.
Angenommen, eine Anwendung erstellt Zusammenfassungen von Finanzdaten, die auf einer scrollbaren Internetseite mit mehreren tausend Datensätzen angezeigt werden. Positive und negative Werte werden dabei farblich in Grün bzw. Rot hervorgehoben.
Nun möchte ein Auftraggeber die Finanzdaten über einen Schwarzweißdrucker paginiert ausgeben. Negative Zahlen sollen dabei zur schnellen Erkennung in Klammern gesetzt werden.
Offenbar muss hierfür neuer Code für die Druckansicht geschrieben werden. Doch wie viel bestehender Code muss dabei angepasst werden?
Gute Softwarearchitektur zeichnet sich dadurch aus, dass möglichst wenig bestehender Code geändert wird. Idealerweise wird nichts Bestehendes modifiziert, sondern lediglich die neue Druckansicht unkompliziert als Erweiterung hinzugefügt.
Wie lässt sich dies realisieren? Durch die konsequente Trennung der Verantwortlichkeiten gemäß dem SRP (Single Responsibility Principle) und die Organisation der Abhängigkeiten nach dem DIP (Dependency Inversion Principle).
Mit dem SRP ergibt sich folgender Datenfluss:
Eine klare Trennung der Datenaufteilung, Algorithmen und Darstellung ist entscheidend. Beispielsweise analysiert ein Algorithmus die Finanzdaten, um einen Bericht zu erstellen. Erst danach werden diese Daten für Visualisierungen aufbereitet. Komponenten werden so organisiert, dass Änderungen oder Erweiterungen minimalen Aufwand erfordern.
Die Komponenten und ihre Referenzen können detailliert visualisiert werden:
Die Abhängigkeiten folgen klar definierten Richtlinien: Ein Pfeil von Klasse A zu Klasse B bedeutet, dass A einen Verweis auf B implementiert, jedoch B keine Kenntnis von A hat. Beispielsweise implementiert der FinanzDatenMapper das FinanzDatenGateway, ohne umgekehrt von diesem abhängig zu sein. Dies gewährleistet unidirektionale Referenzen, wodurch Ringverweise vermieden werden.
Auch eine komprimierte Visualisierung der Komponenten ist möglich:
Unidirektionale Verbindungen bieten den Vorteil, dass eine Komponente A vor Änderungen in Komponente B geschützt bleibt. Zum Beispiel soll der Controller vor Änderungen im Darsteller und in der Ansicht geschützt sein.
Besonders wichtig ist der Schutz des Interactors vor Änderungen vorgelagerter Komponenten, da dieser Geschäftslogik und Datenbankzugriffe beinhaltet. Vorgelagerte Komponenten dienen hauptsächlich der peripheren Kommunikation, wie der Controller zur Darstellung und Ansicht.
Diese Schutzhierarchie definiert die Ansicht als am wenigsten schützenswert und den Interactor als am stärksten zu schützen.
Softwarearchitektur trennt Funktionen anhand von Datenstrukturen, Algorithmen, Darstellungsformen und technischen Anforderungen. Änderungen in der Benutzeroberfläche (z. B. durch das UX-Team) dürfen die Geschäftslogik nicht beeinflussen. Komponenten höherer Schutzgrade werden systematisch vor Änderungen untergeordneter Komponenten geschützt.
Unser Geschäftsführer Tibor Csizmadia und unser Kundenbetreuer Jens Walter stehen Ihnen persönlich zur Verfügung. Profitieren Sie von unserer langjährigen Erfahrung und erhalten Sie eine kompetente Erstberatung in einem unverbindlichen Austausch.