Richtlinie: Klassen implementieren
Diese Richtlinie beschreibt, wie Klassen mit der Modellierumgebung RAD 6.0 implementiert werden.
Beziehungen
Zugehörige Elemente
Hauptbeschreibung

Operationen implementieren

Gehen Sie wie folgt vor, um Operationen zu implementieren:

  • Wählen Sie einen Algorithmus aus.
  • Wählen Sie passende Datenstrukturen für den Algorithmus aus.
  • Definieren Sie neue Klassen und Operationen gemäß Ihren Anforderungen.
  • Codieren Sie die Operation.
Algorithmus auswählen

Viele Operationen sind so einfach, dass Sie aus der Operation und ihrer Spezifikation implementiert werden können.

Nicht triviale Algorithmen werden hauptsächlich aus zwei Gründen benötigt: zum Implementieren komplexer Operationen, für die eine Spezifikation existiert, und zum Optimieren von Operationen, denen ein einfacher aber ineffizienter Algorithmus als Definition dient.

Passende Datenstrukturen für den Algorithmus auswählen

Die Auswahl von Algorithmen beinhaltet auch die Auswahl der zugehörigen Datenstruktur. Viele Implementierungsdatenstrukturen sind Containerklassen, z. B. Arrays, Listen, Warteschlangen, Gruppen, Bags und Variationen dieser Komponenten. Die meisten objektorientierten Sprachen und Programmierumgebungen stellen Klassenbibliotheken mit dieser Art von wieder verwendbaren Komponenten zur Verfügung.

Neue Klassen und Operationen gemäß den Anforderungen definieren

Neue Klassen können beispielsweise definiert werden, um Zwischenergebnisse zu speichern. Einer Klasse können neue Operationen niedriger Ebenen hinzugefügt werden, um eine komplexe Operationen aufzugliedern. Diese Operationen sind häufig private Operationen der Klasse, d. h. sie sind außerhalb der Klasse nicht sichtbar.

Operation codieren

Schreiben Sie den Code für die Operation beginnend mit der Schnittstellenanweisung. Befolgen Sie die geltenden Richtlinien für die Programmierung.

Zustände implementieren

Der Zustand eines Objekts kann durch Referenz auf die Werte seines Attributs implementiert werden, ohne spezielle Darstellung. Die Zustandsübergänge für ein solches Objekt sind in den sich ändernden Werten des Attributs impliziert und das wechselnden Verhalten wird über bedingte Anweisungen programmiert.  Diese Lösung ist für ein komplexes Verhalten nicht geeignet, weil sie normalerweise zu komplexen Strukturen führt, die nur schwer geändert werden können, wenn weitere Zustände hinzugefügt werden oder sich das Verhalten ändert.

Wenn das Verhalten des Designelements (oder seiner Bestandteile) vom Zustand abhängig ist, sind normalerweise ein oder mehrere Zustandsdiagramme vorhanden, die das Verhalten der Modellelemente im Designelement beschreiben. Diese Zustandsdiagramme dienen während der Implementierung als wichtige Eingabe.

Die in den Zustandsdiagrammen gezeigten Zustandsmaschinen machen den Zustand eines Objekts explizit, und die Übergänge und das erforderliche Verhalten sind klar erkennbar. Eine Zustandsmaschine kann auf folgende Arten implementiert werden:

  • Einfache Zustandsmaschinen können implementiert werden, indem ein Attribut definiert wird, das die möglichen Zustände auflistet, und indem das Attribut das Verhalten für die ankommende Nachricht auswählt, beispielsweise in einer Switch-Anweisung in Java oder C++. Diese Lösung lässt sich nicht gut auf komplexe Zustandsmaschinen übertragen und und kann eine niedrige Laufzeitleistung verursachen. Ein Beispiel für diese Methode finden Sie in [DOUG98], Kapitel 4, 4.4.3.
  • Komplexere Zustandsmaschinen können das Zustandsmuster verwenden. Eine Beschreibung des Zustandsmusters finden Sie in [GAM94]. Diese Lösung wird auch in [DOUG98], Kapitel 6, 6.2.3, State Pattern, erläutert.
  • Eine Lösung auf der Basis von Tabellen ist gut geeignet für sehr komplexe Zustandsmaschinen, bei denen eine Änderung auf einfache Weise durchführbar sein muss. Bei dieser Lösung sind für jeden Zustand Einträge in einer Tabelle vorhanden, wobei jeder Eintrag die Eingaben den aufeinanderfolgenden Zuständen und zugehörigen Übergangsaktionen zuordnet. Ein Beispiel für diese Methoden finden Sie unter [DOUG98], Kapitel 6, 6.2.3, State Table Pattern,.

Zustandsmaschinen mit mehreren gleichzeitig vorhandenen Unterzuständen können implementiert werden, indem die Zustandsverwaltung an aktive Objekte delegiert wird (jeweils ein aktives Objekt für jeden Unterzustand), weil gleichzeitig vorhandene Unterzustände unabhängige Verarbeitungen repräsentieren (die trotzdem interagieren können). Jeder Unterzustand kann mittels einer der oben erläuterten Vorgehensweisen verwaltet werden.

Implementierung mittels Delegierung wiederverwenden

Wenn eine Klasse oder Teile einer Klasse durch Wiederverwendung einer vorhandenen Klasse implementiert werden können, verwenden Sie die Delegierung anstelle der Vererbung.

Delegierung bedeutet, dass die Klasse mit Hilfe anderer Klassen implementiert wird. Die Klasse referenziert mittels einer Variablen ein Objekt einer anderen Klasse. Wenn eine Operation aufgerufen wird, ruft sie für die tatsächliche Ausführung eine Operation im referenzierten Objekt (der wieder verwendeten Klasse) auf. Auf diese Weise wird die Zuständigkeit an die andere Klasse übertragen.

Assoziationen implementieren

Eine einseitige Assoziation wird als Zeiger implementiert, d. h. als Attribut, das eine Objektreferenz enthält. Ist die Multiplizität gleich one, dann wird sie als einfacher Zeiger implementiert. Ist die Multiplizität gleich many, dann ist sie eine Menge von Zählern. Ist die many-Seite geordnet, dann kann anstelle einer Menge eine Liste verwendet werden.

Eine zweiseitige Assoziation wird als Attribute in beide Richtungen implementiert, wobei Techniken der einseitigen Assoziation verwendet werden.

Ein qualifizierte Assoziation wird als Referenztabelle im Qualifikationsobjekt implementiert (z. B. eine Smalltalk-Dictionary-Klasse). Die Selektionswerte in der Referenztabelle sind die Qualifikationsmerkmale und die Zielwerte sind die Objekte der anderen Klasse.

Falls ein geordneter Zugriff auf die Qualifikationsmerkmale erforderlich ist, können diese in einem sortierten Array oder einer sortierten Baumstruktur angeordnet werden. In diesem Fall ist die Zugriffszeit proportional zum Protokollieren von N, wobei N die Zahl der Qualifikationsmerkmale ist.

Werden die Qualifikationsmerkmale aus einer kompakten finiten Menge abgerufen, dann können die Qualifikationsmerkmale einem Integer-Bereich zugeordnet werden, und die Assoziation kann effizient als Array implementiert werden. Diese Lösung ist besser geeignet, wenn die Assoziation meistens voll anstatt wenig gefüllt ist, und ist ideal für vollständig gefüllte finite Mengen.

Die meisten objektorientierten Sprachen und Programmierumgebungen stellen Klassenbibliotheken mit wieder verwendbaren Komponenten zur Verfügung, um unterschiedliche Arten von Assoziationen zu implementieren.

Attribute implementieren

Attribute werden auf eine von drei Arten implementiert: durch Verwendung von integrierten primitiven Typen, durch Verwendung einer vorhandenen Klasse oder durch Definition einer neuen Klasse. Die Definition einer neuen Klasse stellt eine flexiblere Lösung dar, bewirkt aber eine unnötige Dereferenzierung. Beispielsweise kann die Sozialversicherungsnummer eines Mitarbeiters entweder als Attribut des Typs "String" (Zeichenfolge) oder als neue Klasse implementiert werden.

Darstellung der alternativen Implementierung eines Attributs

Alternative Implementierungen eines Attributs.

Es kann auch vorkommen, dass Gruppen von Attributen wie im folgenden Beispiel zu neuen Klassen kombiniert werden. Beide Implementierungen sind korrekt.

Line-Implementierungsattribute für Point-Klasse

Die Line-Attribute werden als Assoziationen zu einer Point-Klasse implementiert.