Richtlinie: Designpaket
Ein Designpaket ist ein Konstrukt, das für die Partitionierung des Designmodells verwendet wird. Diese Richtlinie beschreibt, wie Sie Designpakete identifizieren und angeben.
Beziehungen
Zugehörige Elemente
Hauptbeschreibung

Einführung

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.

Sichtbarkeit des Paketinhalts

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.

Kriterien für die Partitionierung mit Paketen

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.

Grenzklassen packen

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.

Im Begleittext beschriebene Abbildung

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.

Im Begleittext beschriebenes Diagramm.

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.

Funktional zusammengehörige Klassen packen

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.

Im Begleittext beschriebenes Diagramm.

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.

Im Begleittext beschriebene Abbildung

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.

Paketkohäsion bewerten

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'.

Im Begleittext beschriebene Abbildung

Um das B-spezifische Verhalten zu isolieren, wird die Steuerungsklasse A, der es an Homogenität fehlt, in zwei Steuerungsklassen A' und A'' aufgeteilt.

Paketabhängigkeiten beschreiben

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.

Im Begleittext beschriebene Abbildung

Das Paket Auftragsbearbeitung ist von Artikelbearbeitung abhängig, weil eine Assoziation zwischen den beiden Klassen in den Paketen besteht.

Paketkoppelung auswerten

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).

Im Begleittext beschriebene Abbildung

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.

Im Begleittext beschriebene Abbildung

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.