Das Designmodell
kann in kleinere Einheiten strukturiert werden, u m es verständlicher zu machen. Durch die Gruppierung von
Designmodellelementen in Paketen und Subsystemen und anschließende Darstellung, wie diese Gruppierungen zueinander in
Beziehung stehen, lässt sich die Gesamtstruktur des Modells einfacher verstehen. Ein Designsubsystem wird als Komponente modelliert, die eine oder mehrere
Schnittstellen realisiert. Weitere Informationen hierzu finden Sie unter Arbeitsergebnis: Designsubsystem und Richtlinie für Arbeitsergebnis: Designsubsystem. Designpakete hingegen werden nur
für die Gruppierung verwendet.
Eine in einem Paket enthaltene Klasse kann öffentlich oder privat sein. Eine öffentliche Klasse
kann von einer anderen Klasse zugeordnet werden. Eine private Klasse kann
nur von den Klassen im Paket zugeordnet werden.
Eine Paketschnittstelle setzt sich aus den öffentlichen Klassen eines Pakets zusammen. Die Paketschnittstelle
(öffentliche Klassen) isoliert und implementiert die Abhängigkeiten in anderen Paketen. Dies vereinfacht die parallele
Entwicklung, da Sie Schnittstellen bereits in einem frühen Stadium entwickeln können und die Entwickler nur über die
Änderungen in den Schnittstellen anderer Pakete informiert werden müssen.
Sie können das Designmodell aus verschiedenen Gründen partitionieren:
-
Sie können Pakete und Subsysteme als Auftrags-, Konfigurations- oder Liefereinheiten verwenden, wenn ein System
fertig gestellt ist.
-
Die Zuordnung der Ressourcen und die Kompetenzen der einzelnen Entwicklungsteams können die Aufteilung des Projekts
auf mehrere Gruppen an unterschiedlichen Standorten erfordern. Subsysteme mit klar definierten Schnittstellen
bieten eine Möglichkeit, Arbeit auf kontrollierte, koordinierte Weise auf Teams zu verteilen, und damit Design und
Implementierung parallel voranschreiten zu lassen.
-
Subsysteme können verwendet werden, um das Designmodell so zu strukturieren, dass es die Benutzertypen
widerspiegelt. Viele Änderungsanfragen stammen von Benutzern. Subsysteme stellen sicher, dass Änderungen eines
bestimmten Benutzertyps nur die Teile des Systems betreffen, die diesem Benutzertyp entsprechen.
-
In einigen Anwendungen dürfen bestimmte Informationen nur für einige wenige Personen zugänglich sein. Mit
Subsystemen können Sie die Vertraulichkeit dort sicherstellen, wo sie erforderlich ist.
-
Wenn Sie ein Support-System erstellen, können Sie diesem mit Subsystemen und Paketen eine Struktur geben, die mit
der Struktur des zu unterstützenden Systems vergleichbar ist. Auf diese Weise können Sie die Verwaltung der beiden
Systeme synchronisieren.
-
Subsysteme werden verwendet, um die
vorhandenen Produkte und Services darzustellen, die das System verwendet (z. B. COTS-Produkte und Bibliotheken),
wie in den folgenden Abschnitten näher erläutert wird.
Wenn die Grenzklassen auf Pakete verteilt werden, können zwei unterschiedliche Strategien angewendet werden. Welche
anzuwenden ist, richtet sich danach, ob künftig mit vielen Änderungen an den Systemschnittstellen zu rechnen ist.
-
Wenn damit zu rechnen ist, dass die Systemschnittstelle ersetzt oder erheblichen Änderungen unterzogen wird, sollte
die Schnittstelle vom Rest des Designmodells abgesondert werden. Wenn die Benutzerschnittstelle geändert wird, sind
dann nur diese Pakete betroffen. Ein Beispiel für eine solch bedeutende Änderung ist das Umschalten von einer
zeilenorientierten Schnittstelle auf eine fensterorientierte Schnittstelle.
Wenn das primäre Ziel die Vereinfachung größerer Schnittstellenänderungen ist, sollten Grenzklassen in ein (oder
mehrere) gesondertes Paket gestellt werden.
-
Wenn keine größeren Schnittstellenänderungen geplant sind, sollten Änderungen an den Systemservices das Leitprinzip
sein und nicht Änderungen an der Schnittstelle. Die Grenzklassen müssen dann zu den Entitäts- und Steuerungsklassen
gestellt werden, mit denen sie funktional zusammengehören. Auf diese Weise lässt sich leichter erkennen, welche
Grenzklassen betroffen sind, wenn eine bestimmte Entitäts- oder Steuerungsklasse geändert wird.
Um Änderungen an den Services des Systems zu vereinfachen, werden die Grenzklassen mit den Klassen gepackt, mit denen
sie funktional zusammengehören.
Verbindliche Grenzklassen, die funktional nicht zu einer Entitäts- oder Steuerungsklasse gehören, sollten zusammen mit
Grenzklassen, die zu derselben Schnittstelle gehören, in gesonderte Pakete gestellt werden.
Wenn eine Grenzklasse zu einem optionalen Service gehört, gruppieren Sie sie zusammen mit den kollaborierenden Klassen
für den Service in einem gesonderten Subsystem. Das Subsystem wird einer optionalen Komponente zugeordnet, die
bereitgestellt wird, wenn die optionale Funktionalität angefordert wird.
Für jede Gruppe von Klassen, die funktional zusammengehören, muss ein Paket angegeben werden. Es gibt verschiedene
praktische Kriterien, die angewendet werden können, um festzustellen, ob zwei Klassen funktional zusammengehören. Diese
sind in absteigender Reihenfolge ihrer Bedeutung im Folgenden aufgelistet:
-
Wenn Änderungen im Verhalten und/oder der Struktur einer Klasse Änderungen in einer anderen Klasse erforderlich
machen, gehören die Klassen funktional zusammen.
Beispiel
Wenn ein neues Attribut zur Entitätsklasse Auftrag hinzugefügt wird, zieht dies wahrscheinlich die
Aktualisierung der Steuerungsklasse Auftragsadministrator nach sich. Deshalb gehören die beiden Klassen zu
demselben Paket, Auftragsbearbeitung.
-
Ob eine Klasse funktional mit ener anderen Klasse zusammengehört, lässt sich feststellen, indem Sie mit einer
Klasse, z. B. einer Entitätsklasse, beginnen und feststellen, welche Auswirkungen das Löschen dieser Klasse vom
System hat. Alle Klassen, die nach dem Löschen einer Klasse überflüssig werden, sind in irgendeiner Weise mit der
entfernten Klasse verknüpft. Überflüssig heißt hier, dass die Klasse nur von der entfernten Klasse verwendet wird
bzw. von der entfernten Klasse abhängig ist.
Beispiel
Das Paket Auftragsbearbeitung enthält die beiden Steuerungsklassen Auftragsadministrator und
Auftragserfassung im Lagerverwaltungssystem. Beide Steuerungsklassen modellieren Services, die sich
auf die Auftragsbearbeitung im Lager beziehen. Alle Auftragsattribute und -beziehungen werden von der
Entitätsklasse Auftrag gespeichert, die nur für die Auftragsbearbeitung existiert. Wenn die Entitätsklasse
entfernt wird, gibt es keine Verwendung mehr für den Auftragsadministrator oder die
Auftragserfassung, da sie nur nützlich sind, wenn der Auftrag vorhanden ist. Deshalb muss die
Entitätsklasse Auftrag in dasselbe System wie die beiden Steuerungsklassen gestellt werden.
Auftragsadministrator und Auftragserfassung gehören zu demselben Paket wie Auftrag, da sie
überflüssig werden, wenn Aufrag vom System entfernt wird.
-
Zwei Objekte können funktional zusammengehören, wenn sie mit einer Vielzahl von Nachrichten interagieren oder eine
andere komplizierte übergreifende Kommunikation haben.
Beispiel
Die Steuerungsklasse Aufgabenausführender sendet und empfängt viele Nachrichten an und von der
Transporterschnittstelle. Dies ist ein Hinweis darauf, dass die Klassen in dasselbe Paket,
Aufgabenbearbeitung, gestellt werden sollten.
-
Eine Grenzklassen kann funktional mit einer bestimmten Entitätsklasse zusammengehören, wenn die Grenzklasse die
Funktion hat, die Entitätsklasse darzustellen.
Beispiel
Die Grenzklasse Palettenformular im Lagerverwaltungssystem stellt eine Instanz der Entitätsklasse
Palette für den Benutzer dar. Jede Palette wird am Bildschirm mit einer Identifikationsnummer
dargestellt. Wenn die Informationen für eine Palette geändert werden, der Palette z. B. auch ein Name
zugewiesen wird, muss die Grenzklasse möglicherweise auch geändert werden. Deshalb sollte Palettenformular
in dasselbe Paket gestellt werden wie Palette.
-
Zwei Klassen können funktional zusammgehören, wenn sie mit demselben Akteur interagieren bzw. von Änderungen im
Akteur betroffen sind. Wenn zwei Klassen nicht mit demselben Akteur interagieren, sollten Sie sie nicht in dasselbe
Paket stellen. Die letzte Regel kann natürlich ignoriert werden, wenn wichtige Gründe vorliegen.
Beispiel
Das Paket Aufgabenbearbeitung im Lagerverwaltungssystem enthält unter anderem die Steuerungsklasse
Aufgabenausführender. Dies ist das einzige Paket mit dem Akteur Transporter, dem physischen
Transporter, der eine Palette in das Lager transportieren kann. Der Akteur interagiert mit der Steuerungsklasse
Aufgabenausführender über die Grenzklasse Transporterschnittstelle. Diese Grenzklasse muss deshalb in
das Paket Aufgabenbearbeitung aufgenommen werden.
Transporterschnittstelle und Aufgabenausführender gehören zu demselben Paket, da beide von Änderungen
im Akteur Transporter betroffen sind.
-
Zwei Klassen können funktional zusammengehören, wenn sie Beziehungen untereinander haben (Assoziationen,
Aggregationen usw.). Natürlich kann dieses Kriterium nicht unbekümmert angewandt werden, kann aber verwendet
werden, wenn keine anderen Kriterien zutreffen.
-
Eine Klasse kann funktional zu der Klasse gehören, die Instanzen von ihr erstellt.
Die folgenden beiden Kriterien bestimmen, dass zwei Klassen nicht in dasselbe Paket gestellt werden sollten:
-
Zwei Klassen, die zu unterschiedlichen Akteuren gehören, sollten nicht in dasselbe Paket gestellt werden.
-
Eine optionale und eine verbindliche Klasse sollten nicht in dasselbe Paket gestellt werden.
Zunächst müssen alle Elemente in einem Paket diese Optionalität haben: Es können keine optionalen Modellelemente in
einem verbindlichen Paket enthalten sein.
Beispiel
Die verbindliche Entitätsklasse Artikeltyp hat unter anderem ein Attribut Aufstockungsschwelle. Die
Aufstockungsfunktion ist jedoch im System optional. Deshalb muss Artikel in zwei Entitätsklassen aufgeteilt
werden, wobei die optione Klasse auf die verbindliche Klasse verweist.
Ein Paket, das als verbindlich eingestuft ist, kann nicht von einem optionalen Paket abhängig sein.
Im Regelfall kann ein Paket nicht von zwei unterschiedlichen Akteuren verwendet werden. Der Grund hierfür ist, dass
eine Änderung im Verhalten eines Akteurs sich nicht auf die anderen Akteure auswirken sollte. Es gibt Ausnahmen von
dieser Regel, z. B. Pakete, die optionale Services enthalten. Pakete dieses Typs dürfen nicht aufgeteilt werden, egal,
von wie vielen Akteure sie verwendet werden. Ein Paket oder eine Klasse, das bzw. die von mehreren Akteuren verwendet
wird, sollte deshalb aufgeteilt werden, sofern das Paket nicht optional ist.
Alle Klassen in einem Paket müssen funktional zusammgehören. Wenn Sie die Kriterien im Abschnitt "Pakete funktional
zusammengehörender Klassen finden" befolgt haben, gehören die Klassen in einem Paket funktional zusammen. Eine
bestimmte Klasse kann jedoch "zu viel" Verhalten oder Beziehungen enthalten, die nicht zur Klasse gehören. In diesem
Fall sollte ein Teil der Klasse in eine vollständig neue Klasse oder eine andere Klasse, die wahrscheinlich zu einem
anderen Paket gehört, extrahiert werden.
Beispiel
Das Verhalten der Steuerungsklasse A in einem Paket soll nicht zu viel von der Klasse B in einem anderen
Paket abhängen. Um das B-spezifische Verhalten zu isolieren, muss die Steuerungsklasse A in zwei
Steuerungsklassen A' und A" aufgeteilt werden. Das B-spezifische Verhalten wird in die neue
Steuerungsklasse A" gestellt, die in dasselbe Paket wie B aufgenommen wird. Die neue Klasse A"
erhält auch eine Beziehung, z. B. eine Generalisierungsbeziehung, zum ursprünglichen Objekt A'.
Um das B-spezifische Verhalten zu isolieren, wird die Steuerungsklasse A, der es an Homogenität fehlt, in
zwei Steuerungsklassen A' und A'' aufgeteilt.
Wenn eine Klasse in einem Paket eine Assoziation zu einer Klasse in einem anderen Paket aufweist, sind diese Pakete
voneinander abhängig. Paketabhängigkeiten werden mit einer Abhängigkeitsbeziehung zwischen den Paketen modelliert. Mit
Abhängigkeitsbeziehungen können die Konsequenzen von Änderungen eingeschätzt werden. Ein Paket, von dem viele Pakete
abhängig sind, ist schwieriger zu ändern als ein Paket, von dem keine Pakete abhängig sind.
Da während der Spezifikation der Pakete mehrere Abhängigkeiten wie diese gefunden werden, müssen diese Beziehungen
während der Arbeit geändert werden. Die Beschreibung einer Abhängigkeitsbeziehung kann Informationen dazu enthalten,
welche Klassenbeziehungen die Abhängigkeiten verursachen. Da damit Informationen eingeführt werden, die schwierieg zu
verwalten sind, sollten diese Informationen nur verwendet werden, wenn sie wichtig und wertvoll sind.
Beispiel
Im Lagerverwaltungssystem besteht eine Abhängigkeitsbeziehung zwischen dem Paket Auftragsbearbeitung und
dem Paket Artikelbearbeitung. Diese Assoziation entsteht, weil die Entitätsklasse Auftrag in der
Auftragsbearbeitung eine Assoziation zur Entitätsklasse Artikeltyp in dem anderen Paket besitzt.
Das Paket Auftragsbearbeitung ist von Artikelbearbeitung abhängig, weil eine Assoziation zwischen den
beiden Klassen in den Paketen besteht.
Paketkoppelung hat Vor- und Nachteile. Vorteile deswegen, weil die Koppelung für Wiederverwendbarkeit steht, und
Nachteile, weil Koppelung Abhängigkeiten bedeutet, die Änderung und Weiterentwicklung des Systems schwieriger machen.
Im Folgenden sind einige allgemeine prinzipielle Vorgehensweisen beschrieben:
-
Pakete sollten keine Überkreuzbeziehungen aufweisen (d. h. gegenseitig abhängig sein).
In diesen Fällen müssen die Pakete reorganisiert werden, um die wechselseitigen Abhängigkeiten zu entfernen.
-
Pakete in unteren Schichten dürfen nicht von Paketen in oberen Schichten abhängig sein. Pakete sollten nur von
Paketen abhängig sein, die sich in derselben oder der direkt untergeordneten Schicht befinden.
In diesen Fällen muss die Funktionalität erneut partitioniert werden. Eine Möglichkeit ist, die Abhängigkeiten in
Schnittstellen zu formulieren und die Schnittstellen in die untergeordnete Schicht zu stellen.
-
Abhängigkeiten sollten im Allgemeinen keine Schichten überspringen, sofern das abhängige Verhalten nicht auf allen
Schichten dasselbe ist. Die Alternative sind schichtenübergreifende Pass-Through-Operationsaufrufe.
-
Pakete sollten nicht von Subsystemen abhängig sein, nur von anderen Paketen oder Schnittstellen.
|