Richtlinie: Designsubsystem
Ein Designsubsystem implementiert das Konzept Softwarekomponente. Diese Richtlinie beschreibt, wie Sie Designsubsysteme identifizieren und angeben.
Beziehungen
Hauptbeschreibung

Subsystemverwendung

Subsysteme können auf verschiedene komplementäre Arten verwendet werden, um das System in Einheiten zu unterteilen, die

  • unabhängig voneinander angeordnet, konfiguriert und bereitgestellt werden können,
  • die unabhängig voneinander entwickelt werden können, solange die Schnittstellen unverändert bleiben,
  • die unabhängig voneinander auf mehreren verteilten Rechenknoten eingesetzt werden können,
  • die unabhängig voneinander geändert werden können, ohne andere Teile des Systems zu beeinträchtigen.

Subsysteme eignen sich somit ideal für die Modellierung von Komponenten, den austauschbaren Assemblierungseinheiten in der komponentenbasierten Entwicklung, die größer sind als eine einzelne Designklasse.

Außerdem können Subsysteme

  • das System in Einheiten einteilen, die eine eingeschränkte Sicherheit für die Schlüsselressourcen gewährleisten,
  • vorhandene Produkte oder externe Systeme im Design darstellen.

Subsysteme identifizieren

Eine komplexe Analyseklasse wird einem Designsubsystem zugeordnet, wenn sie Verhalten zu enthalten scheint, das nicht in der Zuständigkeit einer einzelnen Designklasse allein liegen kann. Eine komplexe Designklasse kann auch zu einem Subsystem werden, wenn sie wahrscheinlich in Form einer Gruppe kollaborierender Klassen implementiert wird.

Subsysteme sind außerdem ein probates Mittel, um Teile des Systems zu identifizieren, die unabhängig von einem anderen Team entwickelt werden. Wenn die kollaborierenden Designelemente zusammen mit ihren Kollaborationen vollständig in einem Paket enthalten sein können, kann ein Subsystem eine stärkere Form der Kapselung unterstützen als ein einfaches Paket. Inhalt und Kollaborationen in einem Subsystem sind vollständig hinter einer oder mehreren Schnittstellen isoliert, so dass der Client des Subsystems nur von der Schnittstelle abhängig ist. Der Designer des Subsystems ist damit vollständig von externen Abhängigkeiten isoliert. Der Designer (bzw. das Designerteam) muss festlegen, wie die Schnittstelle realisiert wird, aber er hat völlige Freiheit, das interne Subsystemdesign zu ändern, ohne damit externe Abhängigkeiten zu beeinträchtigen. In großen Systemen mit weitgehend unabhängigen Teams ist dieser Grad von Entkopplung, kombiniert mit der Architekturumsetzung durch formale Schnittstellen ein schlagkräftiges Argument für die bevorzugte Wahl von Subsystemen gegenüber einfachen Paketen.

Das Designsubsystem wird verwendet, um diese Kollaborationen so zu kapseln, dass den Clients des Subsystems das interne Design des Subsystems völlig verborgen bleibt, selbst wenn sie die vom Subsystem bereitgestellten Services nutzen. Wenn die an einer Kollaboration teilnehmenden Klassen/Subsysteme nur mit einander interagieren, um eine klar definierte Menge von Ergebnissen zu liefern, sollten die Kollaboration und die kollaborierenden Designelemente in einem Subsystem gekapselt werden.

Diese Regel kann auch auf Untergruppen von Kollaborationen angewendet werden. Kollaborationen können vollständig oder teilweise und überall gekapselt und vereinfacht werden. Auf diese Weise wird das Design verständlicher.

Hinweise

Hinweis

Details

Optionalität erkennen Wenn eine bestimmte Kollaboration (oder untergeordnete Kollaboration) optionales Verhalten darstellt, schließen Sie sie in ein Subsystem ein. Features, die entfernt, aktualisiert oder ersetzt werden können, müssen unabhängig davon betrachtet werden.
Benutzerschnittstelle des System betrachten Wenn die Benutzerschnittstelle relativ unabhängig von den Entitätsklassen im System ist (d. h. Benutzerschnittstelle und Entitätsklassen können und werden unabhängig von einander geändert), erstellen Sie Subsysteme, die horizontal integriert werden. Gruppieren Sie zusammengehörige Grenzklassen der Benutzerschnittstelle in einem Subsystem und zusammengehörige Entitätsklassen in einem anderen Subsystem.
Wenn die Benutzerschnittstelle und die Entitätsklassen eng miteinander gekoppelt sind (d. h. eine Änderung in einem Teil löst eine Änderung im anderen aus), erstellen Sie Subsysteme, die vertikal integriert werden. Schließen Sie zusammengehörige Grenz- und Entitätsklassen in ein gemeinsames Subsystem ein.
Akteure anschauen Trennen Sie Funktionalität, die von zwei unterschiedlichen Akteuren verwendet werden, da jeder Akteur die Anforderungen an das System unabhängig ändern kann.
Erstellen Sie Subsysteme, um den Zugriff auf ein externes System oder eine externe Einheit zu kapseln.
Kopplung und Kohäsion zwischen Designelementen betrachten Eng miteinander gekoppelte oder kohäsive Klassen/Subsysteme kollaborieren und stellen gemeinsam eine Gruppe von Services zur Verfügung. Fassen Sie eng miteinander gekoppelte Elemente in Subsystemen zusammen und trennen Sie Elemente, die nur lose gekoppelt sind. Manchmal kann eine lose Kopplung verhindert werden, indem die Klassen in kleinere Klassen mit kohäsiveren Zuständigkeiten aufgeteilt oder Subsysteme entsprechend partitioniert werden.
Substitution anschauen Wenn mehrere Servicestufen für eine bestimmte Funktionalität angegeben sind (z. B. hohe, mittlere und niedrige Verfügbarkeit), stellen Sie jede Servicestufe als separates Subsystem dar, von denen jedes dieselben Schnittstellen realisiert. Auf diese Weise sind die Subsysteme gegeneinander austauschbar.
Verteilung anschauen Obwohl es mehrere Instanzen eines Subsystems geben kann, die auf unterschiedlichen Knoten ausgeführt werden können, ist es in vielen Architekturen nicht möglich, dass eine Instanz einer Komponente auf mehrere Knoten verteilt wird. Wenn Subsystemverhalten auf mehrere Knoten verteilt werden muss, wird empfohlen, das Subsystem in kleinere Subsysteme (die jeweils eine Komponente darstellen) mit einer eingeschränkteren Funktionalität zu zerlegen.   Bestimmen Sie die Funktionalität für jeden Knoten und erstellen Sie für genau diese Funktionalität ein neues Subsystem. Auf diese Weise können Sie die Zuständigkeiten und zugehörigen Elemente des ursprünglichen Subsystems entsprechend verteilen.   Die neuen Subsysteme sind Interna des ursprünglichen Subsystems.

Nachdem Sie das Design in Subsysteme unterteilt haben, aktualisieren Sie die Anwendungsfallrealisierungen entsprechend.

Subsysteme modellieren

Designsubsysteme werden mit UML-Komponenten modelliert. Dieses Konstrukt unterstützt die folgenden Modellierungsmöglichkeiten:

  • Sie kann Klassen gruppieren, um ein Teil eines Systems mit größerer Unterteilung zu definieren.
  • Sie kann die sichtbaren Schnittstellen von der internen Implementierung abgrenzen.
  • Sie kann Instanzen haben, die zur Laufzeit ausgeführt werden.

Beachten Sie die folgenden Hinweise:

  • Jedes Designsubsystem muss einen Namen und eine Kurzbeschreibung erhalten.
  • Die Zuständigkeiten der ursprünglichen Analyseklasse müssen auf das neu erstellte Subsystem übertragen werden. Verwenden Sie die Beschreibung des Subsystems, um die Zuständigkeiten zu dokumentieren.

Anmerkung: UML 2.0 definiert außerdem einen Stereotyp für Komponenten mit dem Namen <<Subsystem>>, der darauf hinweist, dass diese Komponente beispielsweise für die Darstellung großer Strukturen verwendet werden kann. Ein RUP-Designsubsystem kann eine große Struktur sein oder nicht. Beides ist aus der RUP-Perspektive ein Designsubsystem. Der Softwarearchitekt muss entscheiden, ob beispielsweise Komponenten, die sich aus Komponenten zusammensetzen, als <<Subsysteme>> bezeichnet werden.

Subsysteme, die vorhandene Produkte darstellen Seitenanfang

Wenn ein vorhandenes Produkt Schnittstellen exportiert, d. h. Operationen (und möglicherweise Rezeptionen), aber ansonsten alle Details der Implementierung verdeckt, kann es in der logischen Sicht als Subsystem modelliert werden. Beispiele für Produkte, die das System verwendet und die Sie unter Umständen mit einem Subsystem darstellen können, sind:

  • Datenübertragungssoftware (Middleware),
  • Unterstützung für Datenbankzugriffe (Unterstützung für RDBMS-Zuordnung),
  • anwendungsspezifische Produkte.

Einige vorhandene Produkte wie Sammlungen von Typen und Datenstrukturen (z. B. Stacks, Listen und Warteschlangen) lassen sich besser als Pakete darstellen, da sie mehr als Verhalten aufdecken, und es ist gerade der Inhalt des Pakets, der wichtig und hilfreich ist, und nicht das Paket an sich, das einfach nur ein Container ist.  

Gemeinsame Dienstprogramme wie Mathematikbibliotheken können als Subsysteme dargestellt werden, wenn sie lediglich Schnittstellen exportieren. Ob dies jedoch erforderlich oder sinnvoll ist, richtet sich nach der Designerbeurteilung der zu modellierenden Elemente. Subsysteme sind objektorientierte Konstrukte (da sie modellierte Komponenten sind). Ein Subsystem kann Instanzen haben (wenn der Designer es entsprechend angibt). UML unterstützt außerdem die Modellierung von Gruppen globaler Variablen und Prozeduren in Dienstprogrammen. Ein Dienstprogramm (utility) ist ein Stereotyp einer Klasse. Dienstprogramme haben keine Instanzen.  

Wenn Sie das Subsystem für die Darstellung des Produkts definieren, müssen Sie auch eine oder mehrere Schnittstellen definieren, um die Produktschnittstellen darzustellen.

Einschränkungen zur Subsystemabhängigkeit Seitenanfang

Designsubsysteme (die als UML-Komponenten modelliert werden) unterscheiden sich von Paketen in ihrer Semantik. Ein Subsystem stellt Verhalten über eine oder mehrere Schnittstellen bereit, die es realisiert. Pakete stellen kein Verhalten bereit. Sie sind lediglich Container für Elemente, die Verhalten bereitstellen.

Der Grund für die Verwendung eines Subsystems anstelle eines Pakets ist der, dass ein Subsystem seinen Inhalt kapselt und Verhalten nur über seine Schnittstellen bereitstellt. Dies hat im Gegensatz zu einem Paket den Vorteil, dass Inhalt und internes Verhalten eines Subsystems flexibel geändert werden können, solange die Schnittstellen des Subsystems konstant bleiben. Subsysteme sind außerdem 'austauschbare Designelemente'. Wenn zwei <<Realisierungskomponenten>> dieselben Schnittstellen (oder <<Spezifikationskomponente>>) realisieren, sind sie gegeneinander austauschbar.

Um sicherzustellen, dass Subsysteme austauschbare Elemente im Modell sind, müssen einige Regeln beachtet werden:

  • Ein Subsystem sollte so wenig wie möglich Verhalten offen legen. Idealerweise sollte kein Element in einem Subsystem 'öffentlich' sichtbar sein, so dass kein Element außerhalb des Subsystems von der Existenz eines bestimmten Elements im Subsystem abhängig ist. Es gibt diverse Ausnahmen:
    • In einigen Technologien können die Externa eines Subsystems nicht als UML-Schnittstelle modelliert werden. Eine Java-Schnittstelle wird beispielsweise als stereotypierte Klasse modelliert.
    • Das Subsystemdesign kann erfordern, dass Klassen anstelle von UML-Schnittstellen offen gelegt werden. Beispielsweise kann eine Delegierungs- oder Zugriffsklasse verwendet werden, um eine komplexe Kollaboration anderer Klassen zu verbergen. Sie könnten hier auch ein herkömmliches Paket verwenden. Mit einem Subsystem können Sie allerdings die Zielsetzung untermauern, Verhalten zu kapseln und interne Details zu verdecken.

  • Wenn die Externa eines Subsystems keine UML-Schnittstellen sind, ist es häufig hilfreich, die sichtbaren Elemente des Subsystems in einem Diagramm (das Sie beispielsweise "Externe Sicht" nennen könnten) zu zeigen.
  • Ein Subsystem muss seine Abhängigkeiten von Subsystemschnittstellen (und für die zuvor beschriebenen Sonderfälle von öffentlich sichtbaren Elementen des Subsystems) definieren. Außerdem können mehrere Subsysteme Schnittstellen- oder Klassendefinitionen gemeinsam nutzen. In diesem Fall 'importieren' diese Subsysteme den Inhalt der Pakete, die die gemeinsamen Elemente enthalten. Dies ist häufiger der Fall bei Paketen der unteren Schichten in der Architektur, um sicherzustellen, dass gemeinsame Definitionen von Klassen, die zwischen Subsystemen ausgetauscht werden müssen, konsistent definiert sind.

Im Folgenden sehen Sie ein Beispiel für Subsystem- und Paketabhängigkeiten:

Im Begleittext beschriebenes Diagramm

Subsystem- und Paketabhängigkeiten im Designmodell

Subsystemspezifikation und -realisierungSeitenanfang

DefinitionSeitenanfang

Die UML ([UML04]) definiert Folgendes:

Es existieren verschiedene UML-Standardstereotypen für Komponenten, z. B. <<Spezifikation>> (Specification) und <<Realisierung>> (Realization) für die Modellierung von Komponenten mit eindeutigen Spezifikations- und Realisierungsdefinitionen, wobei eine Spezifikation mehrere Realisierungen haben kann.

Eine Komponente mit dem Stereotyp <<Spezifikation>> spezifiziert eine Domäne von Objekten, ohne die physische Implementierung dieser Objekte zu definieren. Sie enthält nur bereitgestellte und erforderliche Schnittstellen und in ihrer Definition keine realisierenden Klassen und Unterkomponenten.

Eine Komponente mit dem Stereotyp <<Realisierung>> (Realization) spezifiziert eine Domäne von Objekten und definiert außerdem die physische Implementierung dieser Objekte. Beispielsweise enthält eine Komponente mit dem Stereotyp <<Realisierung>> (Realization) nur realisierende Klassen und Unterkomponenten, die Verhalten implementieren, das von einer gesonderten Komponente <<Spezifikation>> (Specification) spezifiziert wird.

Die Trennung von Spezifikation und Realisierung lässt im Wesentlichen zwei separate Beschreibungen des Subsystems zu. Die Spezifikation dient als Vertrag, der alles definiert, was ein Client wissen muss, um das Subsystem verwenden zu können. Die Realisierung wird detailliert im internen Design beschrieben, das den Implementierer anleitet. Wenn Sie mehrere Realisierungen unterstützen möchten, erstellen Sie separate "Realisierungssubsysteme" und zeichnen Sie eine Realisierung von jedem Realisierungssubsystem zum Spezifikationssubsystem.

Verwendung

Wenn der interne Zustand und das Verhalten des Subsystems relativ einfach sind, kann es ausreichen, das Subsystem mit den offen gelegten Schnittstellen, Zustandsdiagrammen für die Beschreibung des Verhaltens und beschreibendem Text zu spezifizieren.

Für komplexere interne Zustände und Verhalten können Analyseklassen verwendet werden, um das Subsystem auf einer höheren Abstraktionsebene zu spezifizieren. Für große Systeme mit Systemen kann die Spezifikation eines Subsystems auch Anwendungsfälle enthalten. Weitere Informationen hierzu finden Sie im Whitepaper Developing Large-Scale Systems with the Rational Unified Process.

Eine von der Realisierung gesonderte detaillierte Spezifikation kann in den folgenden Situationen äußerst hilfreich sein:

  • Der interne Zustand oder das Verhalten der Subsystemrealisierung ist komplex, und die Spezifikation muss so einfach wie möglich ausgedrückt werden, damit sie von den Clients effektiv genutzt werden kann.
  • Das Subsystem ist eine wiederverwendbare "Assemblierungskomponente", die für die Integration in mehrere Systeme bestimmt ist (siehe Konzept: Komponente).
  • Die Interna des Subsystems werden voraussichtlich von unterschiedlichen Organisationen entwickelt.
  • Es müssen mehrere Implementierungen des Subsystems erstellt werden.
  • Das Subsystem wird voraussichtlich durch eine andere Version ersetzt, die signifikante interne Änderungen ohne Änderungen am extern sichtbaren Verhalten aufweist.

Die Verwaltung einer separaten Spezifikation bedeutet jedoch Aufwand, weil sichergestellt werden muss, dass die Realisierung des Subsystems mit der Spezifikation kompatibel ist. Die Kriterien dafür, wann und ob gesonderte Spezifikations- und Realisierungsklassen und Kollaborationen erstellt werden sollen, müssen in den projektspezifischen Richtlinien definiert werden.

Abhängigkeiten

Eine Spezifikation muss ihre Abhängigkeiten definieren. Es handelt sich hierbei um die Schnittstellen und sichtbaren Elemente aus anderen Subsystemen und Paketen, die in allen kompatiblen Realisierungen des Subsystems verfügbar sein müssen.

Eine Realisierung kann zusätzliche Abhängigkeiten haben, die vom Designer oder Implementierer eingeführt werden. Beispielsweise könnte eine Dienstprogrammkomponente verwendet werden, um die Implementierung zu vereinfachen, aber die Verwendung dieser Dienstprogrammkomponente ist ein Detail, die den Clients nicht offen gelegt werden muss. Diese zusätzlichen Abhängigkeiten müssen im Rahmen der Realisierung in einem separaten Diagramm erfasst werden.

Beziehung zur Implementierung

Eine vollständig detaillierte Spezifikation definiert alles, was ein Client benötigt, um das Subsystem verwenden zu können. Das bedeutet, dass die offen gelegten Schnittstellen und alle öffentlich sichtbaren Elemente so präzisiert werden müssen, dass sie dem Code 1:1 entsprechen. Analyseklassen, die eingeführt werden, um das Subsystemverhalten zu spezifizieren, sollten auf einer hohen Abstraktionsebene bleiben, da sie von allen Subsystemrealisierungen unabhängig bleiben sollen.

Die Realisierungselemente eines Subsystems müssen eng am Code ausgerichtet sein.

Weitere Informationen zu diesem Thema finden Sie in Technik: Zuordnung von Design zu Code.

UML-1.x-Darstellung

Modellierung

Designsubsysteme können als UML-2.0-Komponenten oder als UML-1.5-Subsysteme modelliert werden. Diese Konstrukte unterstützen nahezu dieselben Modellierungsmöglichkeiten wie Modularität, Kapselung und Instanzen, die zur Laufzeit ausgeführt werden können.

Schauen Sie sich die folgenden zusätzlichen Hinweise zu diesen Modellierungsoptionen an:

  • UML-1.5-Subsystem enthalten explizit die Begriffe "Spezifikation" und "Realisierung" (siehe Definition im Abschnitt Subsystemspezifikation und -realisierung oben). Die UML-2.0-Komponenten unterstützen die Begriffe Spezifikation (in Form einer oder mehrerer bereitgestellter und erforderlicher Schnittstellen) und Realisierung (interne Implementierung, die sich aus einer oder mehreren Klassen und Unterkomponenten zusammensetzt, die das Verhalten realisieren).
  • UML-1.5-Subsysteme sind auch Pakete. UML-2.0-Komponenten haben Paketmerkmale, d. h. sie können eine potenziell umfangreiche Menge von Modellelementen enthalten und importieren.

Im Großen und Ganzen sind diese Notationen jedoch gegeneinander austauschbar. Ob Designsubsysteme als UML-1.5-Subsysteme oder UML-2.0-Komponenten dargestellt werden, ist eine Entscheidung, die in den projektspezifischen Richtlinien für Ihr Projekt dokumentiert werden muss.

Wenn Ihr Tool für visuelle Modellierung UML-1.5-Pakete, aber keine UML-1.5-Subsysteme unterstützt, kann ein Paket mit dem Stereotyp <<Subsystem>> für die Beschreibung eines Subsystems verwendet werden.

Einschränkungen für Subsystemabhängigkeiten

Die Einschränkungen und Erläuterungen aus dem Abschnitt Einschränkungen für Subsystemabhängigkeiten gelten gleichermaßen auch für Designsubsysteme, die als UML-1.5-Subsysteme modelliert werden.

Im Folgenden sehen Sie ein Beispiel für Subsystem- und Paketabhängigkeiten in UML 1.5:



Im Begleittext beschriebenes Diagramm

Subsystem- und Paketabhängigkeiten im Designmodell

Subsystemspezifikation und -realisierung

UML 1.5 definiert Folgendes:

Der Inhalt eines Subsystems wird in zwei Untergruppen eingeteilt: 1) Spezifikationselemente und 2) Realisierungselemente. Die Spezifikationselemente werden zusammen mit den Operationen und Rezeptionen des Subsystems verwendet, um eine abstrakte Spezifikation des von den Realisierungselementen bereitgestellten Verhaltens zu formulieren. Die Sammlung der Realisierungselemente modelliert die Interna der Verhaltenseinheit des physischen Systems.

Die Trennung von Spezifikation und Realisierung lässt im Wesentlichen zwei separate Beschreibungen des Subsystems zu. Die Spezifikation dient als Vertrag, der alles definiert, was ein Client wissen muss, um das Subsystem verwenden zu können. Die Realisierung wird detailliert im internen Design beschrieben, das den Implementierer anleitet.

Eine Option für die Modellierung von Spezifikationen und Realisierungen, falls diese nicht direkt von der Modellierungsumgebung unterstützt werden, ist die, in jedes Subsystem zwei Pakete, Spezifikation und Realisierung, zu stellen.

Eine Motivation für Spezifikationen ist die Unterstützung mehrerer Realisierungen. Dies wird in UML 1.x nicht direkt unterstützt. Wenn Sie mehrere Realisierungen mit UML-1.5-Subsystemen unterstützen möchten, müssen Sie separate "Realisierungssubsysteme" erstellen und eine Realisierung von jedem Realisierungssubsystem zum Spezifikationssubsystem zeichnen.

Im Wesentlichen sind die für Spezifikation und Realisierung in UML 2.0 geltenden Richtlinien auch hier (siehe Verwendung, Abhängigkeiten und Beziehung zur Implementierung).

Zusätzliche Informationen

Lesen Sie auch den Artikel Unterschiede zwischen UML 1.x und UML 2.0.