Herausforderung Brownfield, Teil 5: Explizite Architektur als Ziel für Refaktorisierungen

Seite 4: Event-Based Components

Inhaltsverzeichnis

Modelliert man eine Funktion in kleinen Funktionseinheiten, die jeweils eine Eingabe zu einer Ausgabe verarbeiten, ergibt sich ein Datenflussdiagramm. Es beschreibt, wie Eingabedaten durch diverse Funktionseinheiten hindurchfließen und am Ende als Ausgaben zur Verfügung stehen. Dabei lassen sich auch Benutzerinteraktionen über eine UI als Eingabequelle modellieren. Ein solches Modell ist deutlich abstrakter als Quellcode, lässt sich aber dennoch in Quellcode übersetzen.

Die Herausforderung liegt darin, eine Form der Modellierung zu finden, die mit möglichst wenigen Abhängigkeiten auskommt. Für Datenflüsse ist das gegeben. Hierbei sind die einzelnen Funktionseinheiten nur noch über die Datentypen abhängig, die auf den "Datenleitungen" transportiert werden. Passt der Datentyp einer Ausgabe zum Datentyp der Eingabe einer anderen Funktionseinheit, lassen sich diese beiden hintereinander "schalten". Auf die Weise fließen die Daten von der einen zur anderen Funktionseinheit. Zu welchem Zeitpunkt der Transport geschehen soll, regeln Events. Daher bezeichnen die Autoren und andere diese Form der Umsetzung als Event-Based Components (EBC) (siehe [5]).

Das konsequente Modellieren in Datenflüssen erfordert ein wenig Umdenken, führt aber zu minimalen Abhängigkeiten und damit zu geringer Kopplung. Ferner sind diese Modelle evolvierbar. Änderungen und Erweiterungen lassen sich leicht einbringen, ohne dadurch Implementierungen und Tests ändern zu müssen. Des Weiteren ergibt sich auf die Weise eine klare Trennung zwischen solchen Funktionseinheiten, die Logik implementieren, und solchen, die für die Verbindungen zwischen Funktionseinheiten zuständig sind. Eine Funktionseinheit ist niemals für beides zuständig – entweder sie realisiert Logik oder sie verbindet Funktionseinheiten.

Bei der Implementierung des Modells ist darauf zu achten, dass die Implementierung jederzeit den Entwurf spiegelt. Andernfalls wäre die Modellierung vergebens. Im Modell identifizierte Funktionseinheiten müssen sich später im Code wiederfinden lassen. Umgekehrt sollten Funktionseinheiten im Quellcode auch im Modell zu finden sein. Das stellt sicher, dass das Modell wirklich ein abstraktes Abbild des Quellcodes ist. Dann kann es wie die Wanderkarte als Orientierung dienen. Das Modell fungiert also auch als Dokumentation, nachdem die Implementierung erfolgt ist, und trägt dadurch wesentlich zur Evolvierbarkeit bei.

Um eine modellierte Funktion im Brownfield-Projekt zu implementieren, sind in der Regel Refaktorisierungen erforderlich. Die neue Funktion ist schließlich in den Code zu integrieren. Dazu müssen meist erst mal die Schnittstellen geschaffen werden. Je weniger Code dabei anzupassen ist, desto besser. Schließlich bergen solche Anpassungen das Risiko von Fehlern und sind daher durch automatisierte Tests abzusichern.

Da die Abhängigkeiten bei EBC gering sind, ist eine Integration in Code relativ einfach zu bewerkstelligen. Das liegt maßgeblich daran, dass die Verbindungen zwischen EBC-Funktionseinheiten lediglich als Datenflüsse modelliert sind. Somit sind an der Schnittstelle zum Brownfield-Code lediglich ein- beziehungsweise ausgehende Datenflüsse zu integrieren.