Freitag, 20. Juni 2014

Das Common-Closure Prinzip

Das Common-Closure Prinzip entspricht dem Single-Responsibility Prinzip auf der Ebene physischer Einheiten. Konzeptionell gibt es hier keine Überraschungen, zum Wortlaut allerdings müssen einige Anmerkungen gemacht werden.

Zum Wortlaut des Prinzips

In der ursprünglichen Fassung bezieht Martin das Prinzip wieder auf Packages:
"The classes in a package should be closed together against the same kinds of changes. A change that affects a package affects all the classes in that package.[Granularity1996]
Wie auch für die anderen Package-Prinzipien ersetzt Martin später Package durch Component:
"The classes in a component should be closed together against the same kinds of changes. A change that affects a component affects all the classes in that component and no other components.“ [Martin2002], Hervorhebung durch mich
Der Wortlaut ist in der Fassung von 2002 fast identisch geblieben und wurde nur durch die Forderung "and no other components" ergänzt, wodurch nochmals hervorgehoben wird, dass es insbesondere darum geht, die Auswirkungen künftiger Änderungen lokal einzuschränken.

Ich werde im weiteren Verlauf dieses Artikels wieder allgemein von "physischen Einheiten" sprechen, um überladene Begriffe wie Package oder Component zu vermeiden, siehe hierzu auch meine frühere Erläuterung.

Warum alle?

Beide Formulierungen von Robert C. Martin enthalten, wenn man sie wörtlich nimmt, eine etwas merkwürdig anmutende Forderung: Warum sollte es wünschenswert oder notwendigerweise so sein, dass bei Änderung irgendeines Details einer physischen Einheit alle Elemente der physischen Einheit zu ändern sind. 

Dies scheint weder wünschenswert noch immer der Fall zu sein, da die Modularisierung auf der Ebene der Typen doch hoffentlich in der Lage ist, bestimmte Änderungen vor anderen Typen zu verbergen. Freilich sind unerwünschte Seiteneffekte auch auf Typ-Ebene möglich, aber in einigen Fällen (z. B. bei der Modifikation privater Member) sollte doch einige Sicherheit bestehen, dass die Änderung lokal beschränkt ist und nicht alle anderen Elemente der Einheit betrifft.

Warum Closure?

Ein anderes Problem des Martin'schen Wortlauts ist die Formulierung "closed together against the same kinds of changes". Hier wird (wie ja auch bereits durch den Namen des Prinzips) eine gewisse wörtliche Anlehnung an das Open-Closed Prinzip versucht, die in diesem Kontext eher verwirrend ist. 

Während das Open-Closed Prinzip eigentlich verlangt, dass Software-Einheiten offen für Erweiterungen, aber geschlossen für Änderungen sein sollen, spricht der Martin'sche Wortlaut im zweiten Satz doch explizit von "gemeinsamen Änderungen" (und eben nicht von gemeinsamen Erweiterungen). 

Das könnte so interpretiert werden, dass das Common-Closure Prinzip gerade in solchen Fällen relevant wird, wenn das Open-Closed Prinzip nicht eingehalten werden kann. Dann aber ist die ganze namentliche Anlehnung an das Open-Closed Prinzip, die sich ja auch im Namen Common-Closure Prinzip ausdrückt, eher unangebracht.

Alternativer Wortlaut

Während ich den Namen des Prinzips nicht ändern kann, da er sich nun einmal so etabliert hat, bevorzuge ich für den Wortlaut daher eine prägnantere und weniger fragwürdige Version des Prinzips, die sich an folgende Formulierung von Kirk Knoernschild anlehnt:
"Classes that change together, belong together" [Knoernschild2002]
Da hier überhaupt nicht mehr von der Ebene die Rede ist (together innerhalb welcher Gruppierung?), auf die sich das Prinzip bezieht, schlage ich die folgende Version vor:
Typen, von denen zu erwarten ist, dass sie gemeinsam geändert werden müssen, sollten in derselben physischen Einheit zusammengefasst werden.

Katalogeintrag

Name, Kurzform Common-Closure Prinzip
Synonyme
Common Closure Principle,
CCP
Beschreibung
Typen, von denen zu erwarten ist, dass sie gemeinsam geändert werden müssen, sollten in derselben physischen Einheit zusammengefasst werden.
Erläuterung
Wie bereits das Single-Responsibility Prinzip basiert auch das Common-Closure Prinzip auf Änderungserwartungen. Darin liegt zugleich seine Stärke und seine Schwäche. Stärke, weil das Prinzip ein praktisch anwendbares Kohäsionskriterium liefert. Schwäche, weil Änderungserwartungen oftmals nur schwache und fehlbare Einschätzungen sind. Knoernschild schreibt:
Konzeptionell mag das CCP einfach zu verstehen sein; seine Anwendung kann aber schwierig sein, da wir Klassen in dieser Weise nur dann zusammenzufassen können, wenn wir die Änderungen an diesen Klassen zuverlässig vorhersagen können (…).“ [Knoernschild2002]
Der Nutzen der Zusammenfassung potentiell gemeinsam veränderlicher Klassen zu einer physischen Einheit besteht darin, Kopplungen auf der Ebene der physischen Einheiten zu vermeiden. Mit diesen Kopplungen würde in jedem Fall eine Komplexitätserhöhung einhergehen, da die Kopplungen auf Klassenebene ohnehin existieren, somit also diejenigen auf der Ebene physischer Einheiten zusätzlich entstünden.
Beispiel(e)
  • Gemeinsame Änderung verschiedener Typen wird umso wahrscheinlicher, je mehr Abhängigkeiten zwischen diesen Typen existieren. Wir hatten dies als strukturelle Kohäsion bezeichnet. Konstellationen mit hoher struktureller Kohäsion sind daher konform mit dem Common-Closure Prinzip und sprechen dafür, die betroffenen Typen in einer gemeinsamen physischen Einheit zusammenzufassen.
  • Auch ohne hohe strukturelle Kohäsion können verschiedene Klassen inhaltlich so eng zusammenhängen, dass es wahrscheinlich ist, dass sie im Falle einer Änderung gemeinsam betroffen sind. Ein derartiger Zusammenhang kann beispielsweise durch die fachlichen Anforderungen vorgegeben sein. Beispiele hierfür sind Anforderungen des Gesetzgebers oder der Aufsichtsbehörden eines Geschäftsfelds, die regelmäßig mofiziert werden, wie es etwa in der Finanzindustrie oder im Gesundheitswesen häufig der Fall ist. Funktionen, die eng mit solchen Vorgaben verbunden sind und von denen zu erwarten ist, dass sie behördlich in absehbarer Zeit wieder modifiziert werden, können in physischen Einheiten gebündelt werden.
  • Eine andere typische Situation kann entstehen, wenn zur Handhabung externer Bibliotheken Adapter-Klassen verwendet werden, welche die konkrete Verwendung der Bibliothek in der jeweiligen Anwendung steuern. Da für externe Bibliotheken immer erwartet werden kann, dass sie eines Tages aktualisiert werden müssen, können eventuelle Schnittstellen-Änderungen der Bibliothek innerhalb einer physischen Einheit gekapselt werden, welche die Adapter-Klassen zur Verwendung der Bibliothek zusammenfasst. Insbesondere wenn die Bibliothek in verschiedenen Anwendungen genutzt wird, kann diese Strategie größere Aktualisierungsaufwände bei Versionswechseln sparen.
Historie
  • Zur Historie des Konzepts der Kohäsion, siehe die Historie im Single-Responsibility Prinzip.
  • Die erste Formulierung des Prinzips erfolgte in der C++-Artikelserie [Granularity1996].
  • In [Martin2002] spricht Martin nicht mehr von „packages“ und „package cohesion“, sondern von „components“ und „component cohesion“.
Art des Prinzips
  • Grundlegende Einteilung: Produkt.
  • Technologiebezug: Spezifisch (Objektorientierung).
  • Entwurfsgüte: Strukturprinzip.
  • Handlungsbezug: Erleichterung von Änderung, Überprüfung, Build, Verteilung und Wiederverwendung.
  • Kognitionsbezug: Komplexitätsreduktion.
(Siehe Kategorisierung der Prinzipien.)
Grad der formalen Spezifikation Gering auf Grund des starken Anteils außerhalb der Software liegender Eigenschaften (Änderungserwartungen).
Vorteile
  • Leicht verständlich.
  • Operationalisierung des Konzepts der hohen Kohäsion auf der Basis von Änderungserwartungen. Gut anwendbar, wenn sich künftige Änderungen gut vorhersagen lassen.
  • Das gewählte Konhäsionskriterium steht in Einklang mit dem Konzept der strukturellen Kohäsion.
  • Das Kohäsionskriterium ist positiv, d. h. es schließt die Anwendung weiterer Kohäsionskriterien wie z. B. das Common-Reuse Prinzip nicht aus.
  • Übertragung des von Klassen bekannten Prinzips der hohen Kohäsion bzw. konkreter des Single-Responsibility Prinzips auf physische Einheiten.
Nachteile
  • Nicht anwendbar, wenn künftige Änderungen nicht gut vorhergesagt werden können.
  • Das Kohäsionskriterium kann orthogonal zu anderen Kohäsionskriterien stehen. Andere Aspekte hoher Kohäsion werden ausgeblendet.
  • Der Name des Prinzips ist eher verwirrend. Die beschriebenen physischen Einheiten sind weniger geschlossen (closed) gegen Änderungen, sondern werden mit der Absicht zusammengefasst, die Auswirkungen bestimmter Änderungen lokal zu halten.
Übergeordnete Prinzipien Lokalitätsprinzip
Abgleitete Prinzipien -
Qualitätsmerkmale
Änderbarkeit (+), Wartbarkeit (+), Überprüfbarkeit (+),
Wiederverwendbarkeit (+)

Quellen

[Granularity1996] Granularity, Robert C. Martin, in: IEEE Software. Dezember 1996, S. 4, siehe http://www.objectmentor.com/resources/articles/granularity.pdf

[Knoernschild2002] - Java Design: Objects, UML, and Process, Kirk Knoernschild (2002)

[Martin 2002] – Agile Software Development. Principles, Patterns, and Practices, Robert C. Martin (2002)