Subsystemursprung dokumentieren
Während der Aufgabe Funktionsbereichsanalyse haben wir einige Subsysteme identifiziert, die den von
einer Übersicht über die Geschäftskomponenten empfangenen Eingaben entsprechen (siehe Konzept Modellierung von Geschäftskomponenten). Bei der Prozessdekomposition (Konzept Dekomposition von Geschäftsprozessen) können die identifizierten Aktivitätsknoten
(Blattknoten) den Subsystemen als Operationen oder Services zugeordnet werden, die das Subsystem als Fassade
bereitstellen wird. Die Funktionalität dieser Operationen wird von den funktionalen Komponenten der Servicekomponente
realisiert. Sie können diese Operationen aber auch gruppieren und Schnittstellen zuordnen, die das Subsystem anbietet.
Anhand der nicht funktionalen Anforderungen der Operationen werden die im Subsystem erforderlichen technischen
Komponenten und Services ermittelt.
Es ist wichtig, dass die Beziehung zwischen diesen identifizierten Subsystemen und ihrer ursprünglichen erhalten
bleibt. Falls sowohl die geschäftsrelevanten Arbeitsergebnisse als auch die Arbeitsergebnisse des Servicemodells in UML
angegeben sind, können die Abhängigkeitsinformationen einfach in den Modellen gespeichert werden. Andernfalls sollten
Sie in der Vorlage Servicemodell in Word oder in einem zugehörigen Arbeitsergebnis gespeichert werden.
Hinweise zu unabhängigen Softwareanbietern: Services können mit vorhandenen Subsystemen realisiert werden, z. B.
mit Hilfe von kundenspezifischen Anwendungen, Softwarepaketen und/oder unabhängigen Softwareanbietern. In einigen
Fällen müssen bei der Identifikation neuer Subsysteme Services physisch gruppiert werden, z. B. ausgehend von Kriterien
wie Datenaffinität, Koten, Leistung usw. Hierauf wird im folgenden Abschnitt näher eingegangen. In der Regel erfolgt
jedoch während der Funktionsbereichsanalyse eine Top-Down-Identifizierung von Subsystemen. Die Zuordnung der
Komponenten zu Schichten der Architektur mit dem Ziel, aus nicht funktionalen Anforderungen erwachsenden
Architekturvorgaben Rechnung zu tragen, wird im Abschnitt "Servicerealisierung" erläutert.
Beispiel
Die Ausgabe der Funktionsbereichsanalyse für das Beispiel einer Mietwagenfirma finden Sie in der folgenden
Tabelle:
Domäne
|
Funktionsbereich
|
Subsystem
|
Beschreibung
|
Marketing und Kundenmanagement
|
Kundendienst
|
Kundendienst
|
Stellt alle automatisierten Funktionen für den Funktionsbereich bereit
|
Produkte
|
Werbeaktionsmanagement
|
Werbeaktionsmanagement
|
Stellt alle automatisierten Funktionen für den Funktionsbereich bereit
|
Logistik für den Wagenpark
|
Verwaltung des Wagenparks
|
Verwaltung des Wagenparks
|
Stellt alle automatisierten Funktionen für den Funktionsbereich bereit
|
Verwaltung der Vermietungen
|
Vermietung
|
Vermietung
|
Stellt alle automatisierten Funktionen für den Funktionsbereich bereit
|
Verwaltung der Vermietungen
|
Reservierungen
|
Reservierungen
|
Stellt alle automatisierten Funktionen für den Funktionsbereich bereit
|
Verwaltung der Vermietungen
|
Preisgestaltung
|
Preisgestaltung
|
Stellt alle automatisierten Funktionen für den Funktionsbereich bereit
|
Das UML-Modell, das sich aus den oben identifizierten Subsystemen ergibt, würde wie folgt aussehen. Beachten Sie, dass
die Subsystemabhängigkeiten bereits im nachfolgend gezeigten Modell enthalten sind.
Für jedes Subsystem sollten die vom Designsubsystem beschriebenen Details dokumentiert oder in einem
Servicemodell im Dokumentformat (siehe Vorlage Servicemodell in Word) bzw. in einem Format wie dem folgenden erfasst werden.
Name
|
Reservierung
|
Beschreibung
|
Mit dem Subsystem Reservierung werden Mietwagenreservierungen erstellt und verwaltet.
|
Schnittstellen
|
-
Fahrzeug reservieren
-
Reservierung ändern
-
Informationen zu Optionen anfordern
-
Mietvertrag bestätigen
-
Reservierung suchen
-
Reservierung stornieren
|
Funktionen
|
-
Fahrzeug reservieren
-
Reservierung ändern
-
Informationen zu Optionen anfordern
-
Mietvertrag bestätigen
-
Reservierung suchen
-
Reservierung stornieren
|
Abhängigkeiten
|
Keine
|
Nicht funktionale Anforderungen
|
Keine
|
|
Servicekomponentenmuster identifizieren und anwenden
In der Richtlinie Servicekomponentenmuster werden nicht nur die verschiedenen Komponentenarten
vorgestellt, die normalerweise zur Implementierung der während dieser Aufgabe identifizierten Subsysteme verwendet
werden, sondern auch eine Reihe von Mustern, die eine skalierbare und flexible Implementierung dieser Subsysteme
ermöglichen. Diese Muster können als Teil der Architektur eines Projekts angegeben werden. Die Liste der genannten
Muster ist selbstverständlich nicht vollständig.
Die Auswahl oder Anpassung eines bestimmten Musters hängt von folgenden Faktoren ab:
-
den funktionalen und nicht funktionalen Anforderungen der Lösung und des jeweiligen Subsystems
-
dem Leistungsspektrum und der Servicequalität von Middleware, in der die Komponenten implementiert werden
-
den Kosten bzw. der Komplexität verschiedener Muster sowie dem Kompromiss, der hinsichtlich des Nutzens dieser
Muster gefunden werden muss
|
Servicekomponente identifizieren
Subsysteme selbst sind keine IT-Assets und nicht in der IT-Infrastruktur implementierbar. Sie stellen eher eine Brücke
zwischen der Geschäftssicht und der IT-Sicht dar. Jedes Subsystem wird von einer oder mehreren Servicekomponente(n)
realisiert. Diese Komponenten sind unternehmensweite Assets (ein verwaltetes Softwareelement mit garantierter
Verfügbarkeit, Lastausgleich, Sicherheit, Leistung und Versionssteuerung). Eine Servicekomponente wird wiederum von
mehreren funktionalen und technischen Komponenten realisiert. Schauen Sie sich dazu die folgende Abbildung an.
Im Allgemeinen wird für jeden Service, der einem Subsystem zugeordnet ist, eine Servicekomponente benötigt. Innerhalb
eines Subsystems können mehrere Servicekomponenten funktionale und technische Komponenten gemeinsam nutzen.
|
Funktionale Komponenten identifizieren
Funktionale Komponenten stellen zusätzliche Geschäftsfunktionen für eine Servicekomponente zur Verfügung. Das
Leistungsspektrum einer Servicekomponente ist in mehrfacher Hinsicht vollständig von den funktionalen Komponenten und
der auf diesen implementierten zusätzlichen Geschäftslogik abhängig.
Funktionale Komponenten finden sich häufig unter den Typmanagern; dies sind Komponenten für die Verwaltung eines
bestimmten Domänenelements, z. B. eines Fahrzeugs, eines Kunden, eines Zeitplans usw. Wir möchten hier allerdings
klarstellen, dass diese Domänenelemente in den meisten Fällen keine einfachen Strukturen, sondern wenig differenzierte
grafische Darstellungen von Daten sind.
Beispiel
Wenn wir uns das Beispiel "Rent-a-Car" anschauen, stellen wir fest, dass die Servicekomponente Reservierung in der Lage
sein muss, die Details zum Kunden, zur gewünschten Ausleihstation und zu den verfügbaren Fahrzeugen der angegebenen
Klasse zu überblicken. Darüber hinaus muss die Einschätzung des Kunden ermittelt werden, damit bei auftretenden
Problemen, z. B. bei Nichtverfügbarkeit von Fahrzeugen, das gewünschte Serviceniveau sichergestellt werden kann. Das
folgende Diagramm veranschaulicht das Komponentenmodell für die Reservierung.

|
Technische Komponenten identifizieren
Technische Komponenten oder Infrastrukturkomponenten dienen dazu, horizontale Plattformfunktionen bereitzustellen.
Diese Funktionen überschreiten die Grenzen von Geschäftsdomänen und sind daher nicht für eine Geschäftsdomäne
spezifisch. Solche technischen Services werden häufig von Middlewareprodukten zur Verfügung gestellt, zu denen auch
Betriebssysteme gehören. Sie werden direkt von der Servicekomponente genutzt oder von den funktionalen Komponenten, auf
die die Servicekomponente zurückgreift.
Beispiel
Jetzt können wir das Komponentenmodell für "Rent-a-Car" (siehe obige Beschreibung der funktionalen Komponenten)
vervollständigen, indem wir zwei technische Komponenten in das Modell aufnehmen. Eine der Komponenten ist für die
Reservierung bestimmt, um den Abschluss einer Reservierungsanfrage zu protokollieren. Die andere Komponente zeigt an,
dass die Komponenten Fahrzeug und Standort für die persistente Speicherung ihrer Daten auf EJB-Services angewiesen
sind.
Alternativ dazu können Sie die erforderlichen Komponenten und ihre Beziehung zu den zuvor identifizierten Services in
Tabellenform ausdrücken. Schauen Sie sich dazu die folgende Abbildung an.

|
Subsystemverhalten auf Subsystemelemente verteilen
Zweck
|
Internes Verhalten des Subsystems angeben.
Neue Designklassen oder Designsubsysteme identifizieren, die erforderlich
sind, um die Anforderungen an das Verhalten des Subsystems zu erfüllen.
|
Das externe Verhalten eines Subsystems wird primär von den verwendeten Schnittstellen definiert. Wenn ein Subsystem
eine Schnittstelle realisiert, verpflichtet es sich damit, jede einzelne Operation, die in der Schnittstelle definiert
ist, zu unterstützen. Die Operation wiederum kann von einer Operation in einem Designelement (z. B. Designklasse oder Designsubsystem) im Subsystem realisiert werden. Diese Operation
setzt möglicherweise eine Kollaboration mit anderen Designelementen voraus.
Die Kollaborationen von Modellelementen innerhalb des Subsystems müssen mit Ablaufdiagrammen dokumentiert werden, die
zeigen, wie das Subsystemverhalten realisiert wird. Jede Operation in einer Schnittstelle, die vom Subsystem realisiert
wird, muss mindestens ein dokumentiertes Ablaufdiagramm haben. Dieses Diagramm, dessen Eigner das Subsystem ist, wird
verwendet, um das interne Verhalten des Subsystems zu entwerfen.
Wenn das Verhalten des Subsystems in hohem Maße zustandsabhängig ist und eine oder mehrere Steuerungs-Threads
darstellt, sind Zustandsmaschinen in der Regel hilfreicher, um das Verhalten des Subsystems zu beschreiben.
Zustandsmaschinen werden in diesem Kontext häufig zusammen mit aktiven Klassen verwendet, um eine Dekomposition der
Steuerungs-Threads des Subsystems (oder der Subsysteme in diesem Fall) darzustellen, und werden in Zustandsdiagrammen
beschrieben (siehe Richtlinie:
Zustandsdiagramm). In Echtzeitsystemen wird das Verhalten von Kapseln auch mit Zustandsmaschinen beschrieben. Das Subsystem kann unabhängige Ausführungs-Threads enthalten, die von aktiven Klassen dargestellt
werden.
In Echtzeitsystemen werden Kapseln
verwendet, um diese Threads zu kapseln.
Beispiel:
Die Kollaboration von Subsystemen, die ein gefordertes Verhalten des Systems erbringen, kann mit Ablaufdiagrammen
beschrieben werden:
Dieses Diagramm zeigt, wie die Schnittstellen der Subsysteme für ein Szenario verwendet werden. Für das Subsystem
"Netzverwaltung" sehen Sie die spezifischen Schnittstellen (ICoordinator in diesem Fall) und die Operationen, die das
Subsystem unterstützen muss. Sie sehen auch, dass das Subsystem "Netzverwaltung" von den Schnittstellen IBHandler und
IAHandler abhängig ist.
Wenn Sie sich das Subsystem anschauen, sehen Sie, wie die Schnittstelle ICoordinator realisiert wird:
Die Klasse Koordinator agiert als "Proxy" für die Schnittstelle ICoordinator, bearbeitet die Schnittstellenoperationen
und koordiniert das Schnittstellenverhalten.
Dieses "interne" Ablaufdiagramm zeigt exakt, welche Klassen die Schnittstelle unterstützen, was intern passieren muss,
damit die Funktionalität des Subsystems bereitgestellt werden kann, und welche Klassen Nachrichten aus dem Subsystem
senden. Das Diagramm veranschaulicht das interne Design und ist wichtig für Subsysteme mit komplexen internen Designs.
Es erleichtert außerdem das Verständnis des Subsystemverhaltens und kann somit hoffentlich in anderen Kontexten
wiederverwendet werden.
Wenn Sie solche "Schnittstellenrealisierungsdiagramme" erstellen, müssen Sie möglicherweise neue Klassen und Subsysteme
erstellen, die das erforderliche Verhalten erbringen. Der Prozess gleicht dem Prozess, der in der Anwendungsfallanalyse
definiert ist, aber anstelle von Anwendungsfällen wird hier mit Schnittstellenoperationen gearbeitet. Geben Sie für
jede Schnittstellenoperation die Klassen (bzw. für komplexes Verhalten ein Subsystem) im aktuellen Subsystem an, die
für die Durchführung der Operation erforderlich sind. Erstellen Sie neue Klassen/Subsysteme, wenn die vorhandenen
Klassen/Subsysteme das erforderliche Verhalten nicht aufweisen (versuchen Sie es jedoch zuerst mit Wiederverwendung).
Wenn neue Designelemente erstellt werden, müssen Subsysteminhalt und -schnittstellen neu überdacht werden. Vermeiden
Sie die Verwendung derselben Klasse in zwei unterschiedlichen Subsystemen. Die Existenz einer solchen Klasse weist
darauf hin, dass die Subsystemgrenzen nicht klar gezogen sind. Greifen Sie in regelmäßigen Abständen auf die Aufgabe Designelemente identifizieren zurück, um die Zuständigkeiten der
Subsysteme zu überprüfen.
Manchmal ist es hilfreich, zwei separate interne Modell des Subsystems zu erstellen - eine Spezifikation für den
Subsystemclient und eine Realisierung für die Implementierer. Die Spezifikation kann "ideale" Klassen und
Kollaborationen enthalten, um das Verhalten des Subsystems zu beschreiben. Die Realisierung hingegen lehnt sich enger
an die Implementierung an und kann zur Implementierung weiterentwickelt werden. Weitere Informationen zur Spezifikation
und Realisierung von Designsubsystemen finden Sie in Richtlinie für Arbeitsergebnis: Designsubsystem, Subsystemspezifikation und
-realisierung.
|
Subsystemelemente dokumentieren
Zweck
|
Interne Struktur des Subsystems dokumentieren
|
Um die interne Struktur des Subsystems zu dokumentieren, erstellen Sie ein oder mehrere Klassendiagramme, die die im
Subsystem enthaltenen Elemente und ihre Assoziationen zueinander zeigen. Ein Klassendiagramm sollte zwar ausreichen,
aber zur Verringerung der Komplexität und zur besseren Verständlichkeit können auch mehrere verwendet werden.
Schauen Sie sich das folgende Beispielklassendiagramm an:
Beispielklassendiagramm für Auftragserfassungssystem
Modelliert als Komponente kann der interne Inhalt eines Subsystems alternativ im Komponentenrechteck in einem
Komponentendiagramm dargestellt werden. Diese Darstellung erlaubt Ihnen außerdem, die Interaktionspunkte des Subsystems
zu anderen Teilen des Systems (über seine Schnittstellen) einzufügen.
Das folgende Komponentendiagramm zeigt das Subsystem Auftrag, seinen internen Inhalt sowie die bereitgestellten und
erforderlichen Schnittstellen.
Beispielkomponentendiagramm für Subsystem Auftrag
Da eine Komponente eine strukturierte Klasse ist, kann ein hoher Kapselungsgrad erreicht werden, indem
eingehende Kommunikation über Ports geleitet wird, die deklarierten Schnittstellen entsprechen. Dies präzisiert die
Spezifikation und die gegenseitige Verbindungen für diese Komponente noch weiter. In dieser Darstellung können Sie
Instanzen von Teilen über Konnektoren verknüpfen, so dass sie eine bestimmte Rolle in der Komponentenimplementierung
übernehmen. Weitere Informationen hierzu finden Sie in Strukturierte
Klasse.
Schauen Sie sich das folgende Beispiel für ein zusammengesetztes Strukturdiagramm für das Subsystem Auftrag mit
Schnittstellen und Ports an.
Beispiel für ein zusammengesetztes Strukturdiagramm für das Subsystem Auftrag
Zusätzlich kann ein Zustandsdiagramm erforderlich sein, um die möglichen Zustände eines Subsystems zu dokumentieren.
Informationen hierzu finden Sie in Technik:
Zustandsdiagramm.
Die Beschreibung der im Subsystem enthaltenen Klassen selbst erfolgt beim Klassendesign.
|
Subsystemabhängigkeiten beschreiben
Zweck
|
Schnittstellen dokumentieren, von denen das Subsystem abhängig ist.
|
Wenn ein in einem Subsystem enthaltenes Element Verhalten eines Elements in einem anderen Subsystem verwendet, entsteht
zwischen den Subsystemen eine Abhängigkeit. Um die Wiederverwendung zu verbessern und Verwaltungsabhängigkeiten zu
verringern, können Sie diese Situation mit Hilfe einer Abhängigkeit von einer bestimmten Schnittstelle des Subsystems und nicht vom Subsystemselbst oder von
dem im Subsystem enthaltenen Element beschreiben.
Es gibt zweierlei Gründe:
-
Es soll möglich sein, ein Modellelement (einschließlich seiner Subsysteme) durch ein anderes zu ersetzen, sofern
beide dasselbe Verhalten aufweisen. Das erforderliche Verhalten wird mit Schnittstellen beschrieben. Deshalb
sollten auch alle Verhaltensanforderungen, die ein Modellelement an ein anderes stellt, mit Schnittstellen
beschrieben werden.
-
Der Designer soll völlige Freiheit beim Design des internen Verhaltens des Subsystems haben, sofern das
Subsystem das richtige externe Verhalten erbringt. Wenn ein Modellelement in einem Subsystem auf ein Modellelement
in einem anderen Subsystem verweist, kann der Designer dieses Modellelement nicht mehr entfernen oder das Verhalten
dieses Modellelements auf andere Modellelemente verteilen. Deshalb ist das System labiler.
Vergewissern Sie sich beim Erstellen von Abhängigkeiten, dass keine direkten Abhängigkeiten oder Assoziationen zwischen
Modellelementen im Subsystem und Modellelementen in anderen Subsystemen bestehen. Stellen Sie außerdem sicher, dass es
keine Schleifenabhängigkeiten zwischen Subsystemen und Schnittstellen gibt. Es ist nicht möglich, dass ein Subsystem
eine Schnittstelle realisiert und gleichzeitig von dieser Schnittstelle abhängig ist.
Abhängigkeiten zwischen Subsystemen und zwischen Subsystemen und Paketen können wie gezeigt direkt gezeichnet werden.
Wenn Abhängigkeiten auf diese Weise gezeichnet werden, gibt die Abhängigkeit an, dass ein Subsystem (z. B.
Rechnungsverwaltung) direkt von einem anderen Subsystem (Terminierung von Zahlungen) abhängig ist.
Beispiel für Subsystemschichten mit direkten Abhängigkeiten
Wenn es möglich ist, dass ein Subsystem durch ein anderes (das dieselben Schnittstellen hat) ersetzt wird, kann die
Abhängigkeit zu einer vom Subsystem realisierten Schnittstelle anstatt zum Subsystem selbst gezeichnet werden. Auf
diese Weise kann jedes andere Modellelement (Subsystem oder Klasse), das dieselbe Schnittstelle realisiert, verwendet
werden. Mit Schnittstellenabhängigkeiten können flexible Frameworks mit austauschbaren Designelementen entworfen
werden.
Beispiel für Subsystemschichten mit Schnittstellenabhängigkeiten
|
|