Ports erstellen und an Protokolle binden
Machen Sie sich Gedanken über die Zuständigkeiten der Kapsel und erstellen Sie eine erste Gruppe von Port-Klassen.
Diese Port-Klassen sind die 'Schnittstellen' zur Kapsel. Port-Klassen stellen die Realisierung eines Protokolls dar, das wiederum eine Gruppe von Eingangs- und
Ausgangssignalen für die Kommunikation mit Kapseln darstellt.
Verwenden Sie beim Erstellen von Ports die Seite Prüfliste: Protokoll,
um festzustellen, ob das Protokoll geeignet ist. Der Port muss eine Gruppe zusammengehöriger Zuständigkeiten
darstellen. Wenn Sie ein geeignetes Protokoll haben, kann dieses für mehrere Kapseln wiederverwendet werden. Nach der
Auswahl des geeigneten Protokolls müssen Sie den Port an dieses Protokoll binden.
|
Kapselinteraktionen validieren
Nachdem die Ports an Protokolle gebunden wurden, muss das externe Verhalten der Kapsel ausgewertet und validiert
werden. Testen Sie mit manuellen Walkthrough-Techniken oder automatisierten Simulationstools das Verhalten der Kapsel,
indem Sie die Ereignisse testen, die das Kapselverhalten zum Ausdruck bringen. Bei der Validierung werden auch die
Kapseln berücksichtigt, die mit der entworfenen Kapsel interagieren. Schreiben Sie mit Hilfe von automatisierten Tools
Stub-Code in der Kapsel, der ein Testen der Ports ermöglicht. Wenn in der Protokoll- oder Port-Definition oder in den
Kapselzuständigkeiten Fehler gefunden werden, müssen Sie die erforderlichen Änderungen an diesen Definitionen
vornehmen.
|
Zustandsmaschine für Kapsel definieren
Nach der Validierung der Kapsel-Ports und -protokolle müssen Sie das interne Verhalten der Kapsel definieren. das
Verhalten der Kapsel wird in einem Zustandsdiagramm definiert. Referenz: Richtlinie:
Zustandsdiagramm. Weitere allgemeine Informationen zu Kapseln können Sie den Seiten Richtlinie: Kapsel und Prüfliste: Kapsel
entnehmen.
Ermitteln Sie zunächst die Zustände, die die Kapsel annehmen kann. Die Zustände müssen eindeutig (eine Kapsel kann
nicht gleichzeitig zwei Zustände annehmen) und beschreibend sein. Weitere Informationen hierzu finden Sie auf den
Seiten zu den entsprechenden Richtlinien und Prüfpunkten.
Nach der Definition der Zustände müssen Sie sich Gedanken über die Übergänge zwischen den Zuständen machen.
Übergangscode sollte sich wie abstrakter Anwendungspseudocode lesen lassen und hauptsächlich aus
Echtzeitserviceaufrufen des Betriebssystems, z. B. Rahmenservices, Zeitservices, Port-Operationen, Kapseloperationen
und Operationen passiver Klassen, bestehen.
Berücksichtigen Sie beim Hinzufügen von Detailcode für einen Kapselübergang Folgendes:
-
Wenn der Code auch für andere Übergänge sinnvoll ist, sollten Sie ihn an eine Kapseloperation delegieren.
-
Prüfen Sie, ob der Code Funktionalität implementiert, die der Zuständigkeit der Kapsel entspricht.
Berücksichtigen Sie beim Definieren einer Kapseloperation Folgendes:
-
Prüfen Sie, ob die Funktion allgemein in jedem Übergang in der Kapsel verwendbar ist und ob ausgeführte Arbeiten
auch an anderen Stellen im System hilfreich sind. Wenn ja, sollten Sie die Funktion an eine passive Klassenfunktion
delegieren.
-
Wenn der Code zu anwendungsspezifisch ist, um in einer bestimmten Datenklasse gespeichert zu werden, sollten Sie
eine zusätzliche Datenklasse als Abstraktion für diesen Code erstellen.
-
Wenn der Code Datenstrukturen bearbeitet (z. B. Listen verwaltet) oder komplexe (mehr als 1 Zeile) Berechnungen
durchführt, sollte er in eine Datenklasse gestellt werden.
|
Anforderungen für passive Klassen definieren
Untersuchen Sie basierend auf den Zustandsmaschinen der Kapsel die passiven Klassen, die von der Kapsel referenziert
werden. Wenn es neue Anforderungen für diese Klassen gibt, müssen Änderungsanfragen für die erforderlichen Änderungen
generiert werden. Falls neue Klassen identifiziert wurden, müssen die Anforderungen für diese Klassen (insbesondere die
erforderlichen Operationen in diesen Klassen) zusammengestellt und die Klassen erstellt werden. Diese Klassen werden
ausführlicher auf der Seite Aufgabe: Klassendesign beschrieben.
|
Kapselvererbung einführen
Kapselvererbung wird verwendet, um Generalisierungsspezialisierung zu implementieren, Polymorphie zu nutzen und um die
Implementierung wiederzuverwenden. Das Schlüsselwort ist hier 'Implementierung'. Es ist eine Technik, die primär
eingesetzt wird, um die interne Struktur von Kapseln und nicht das externe Verhalten von Kapseln wiederzuverwenden.
Vererbung wird häufig fälschlicherweise eingesetzt, um etwas zu erreichen, was mit einfacheren Designtechniken viel
komfortabler zu erreichen ist.
Vererbung für Generalisierungsspezialisierung verwenden
Es gibt drei Arten von Vererbung. Diese sind im Folgenden in aufsteigender Reihenfolge ihrer Komplexität aufgelistet:
-
Schnittstellenvererbung - Es werden nur Ports und Protokolle vererbt. Diese Art der Vererbung ist die
empfohlene.
-
Strukturvererbung - Es werden Schnittstellen- und strukturelle Containerhierarchien vererbt (hilfreich für
Frameworks).
-
Verhaltensvererbung - Zusätzlich zur Schnittstellen- und Strukturvererbung werden Verhaltenscode und
Zustandsmaschinen wiederverwendet.
Struktur- und Verhaltensvererbung werfen verschiedene Probleme auf:
-
Aufgrund des starken Kopplungsgrads durch die Vererbung sind Änderungen an der Unterklassenkaskadierung
erforderlich, wenn Änderungen an Superklassen vorgenommen werden.
-
Die Erfordernis, Verhalten und Struktur von Superklassen in Unterklassen überschreiben und löschen zu müssen, weist
auf eine nicht angemessene Verwendung der Vererbung hin (gewöhnlich für taktische Wiederverwendung von Code). Das
Refactoring von Klassen und Kapseln und die entsprechende Verwendung von Delegierung ist eine weitaus angemessenere
Strategie.
-
Vererbung bedeutet, dass Designentscheidungen in der Klassenhierarchie nach oben verschoben werden, was zu
unerwünschten Design- und Kompilierungsabhängigkeiten führt.
Weitere Probleme sind:
-
Entscheidungen sind möglicherweise nicht in allen Verwendungssituationen angemessen.
-
Die Einführung von Vererbung macht die Wiederverwendung schwieriger, da Designelemente enger gekoppelt sind.
-
Das Design wird instabiler, weil alle neuen Anforderungen, die die Entscheidung ungültig machen, größere Probleme
aufwerfen.
-
Das Design muss extrem flexibel gestaltet werden, um solche Probleme aufzufangen, was häufig schwierig ist. Dies
ist es, was den meisten Aufwand beim Design wiederverwendbarer Frameworks erzeugt!
Alle Designs, die Struktur und Verhalten enthalten, haben integrierte Entscheidungen und Annahmen (entweder explizit
oder implizit). Die kritische Frage, die Sie sich hier stellen müssen, ist folgende: "Sind Sie absolut sicher, dass die
Entscheidung/Annahme immer gültig ist?" Wenn nicht, müssen Sie überlegen, was getan werden kann, um die Entscheidung zu
entfernen oder zu ändern.
|
Kapselverhalten validieren
Zuletzt muss das Verhalten der Kapsel ausgewertet und validiert werden. Testen Sie mit manuellen Walkthrough-Techniken
oder automatisierten Simulationstools das Verhalten der Kapsel, indem Sie die Ereignisse testen, die das
Kapselverhalten zum Ausdruck bringen. Außerdem sollte die interne Struktur der Kapsel geprüft und sichergestellt
werden, dass nicht nur das externe Verhalten, sondern auch die interne Implementierung dieses Verhaltens geprüft wird.
Möglicherweise muss mit automatisierten Tools Stub-Code geschrieben werden, um die Implementierung passiver
Datenklassen und externer Kapseln, mit denen die Kapsel interagiert, zu simulieren. Mängel sollten dokumentiert und die
entsprechenden Änderungen an den Kapseldefinitionen vorgenommen werden.
|
|