Richtlinie: Designklasse
Eine Designklasse stellt ein Designelement dar, das direkt Code zugeordnet wird. Diese Richtlinie beschreibt, wie eine Designklasse entwickelt wird.
Beziehungen
Hauptbeschreibung

Definition

Eine Designklasse ist eine Abstraktion einer oder mehrerer Klassen in der Implementierung des Systems, welchen Klassen exakt, richtet sich nach der Implementierungssprache. In einer objektorientierten Sprache wie C++ kann eine Klasse beispielsweise einer einfachen Klasse entsprechen. In Ada kann eine Klasse einem Typ mit Kennung entsprechen, der in dem sichtbaren Teil eines Pakets definiert ist.

Klassen definieren Objekte, die wiederum die Anwendungsfälle realisieren (implementieren). Eine Klasse entstammt den Anforderungen, die die Anwendungsfallrealisierungen an die im System erforderlichen Objekte stellen, sowie jedem zuvor entwickelten Objektmodell.

Ob eine Klasse tauglich ist oder nicht, ist im Wesentlichen von der Implementierungsumgebung abhängig. Die richtige Größe der Klasse und ihrer Klasse richtet sich beispielsweise nach der Programmiersprache. Was richtig in Ada ist, kann in Smalltalk falsch sein. Klassen müssen einem bestimmten Phänomen in der Implementierungssprache zugeordnet sein, und die Klassen müssen so strukturiert sein, dass die Zuordnung sauberen Code ergibt.

Obwohl die Eigenheiten der Implementierungssprache Einfluss auf das Designmodell haben, müssen Sie die Klassenstruktur so gestalten, dass sie verständlich ist und einfach geändert werden kann. Sie sollten das Design so gestalten, als hätten Sie Klassen und Kapselung, selbst wenn die Implementierungssprache dies nicht unterstützt.

Operationen

Die einzige Möglichkeit, mit der andere Objekte auf die Attribute oder Beziehungen eines Objekts zugreifen bzw. diese beeinflussen können, sind Operationen. Die Operationen eines Objekts werden von seiner Klasse definiert. Mit Operationen kann ein bestimmtes Verhalten erzeugt werden, das die Attribute und Beziehungen des Objekts beeinflussen und die Ausführung anderer Operationen bewirken kann. Eine Operation entspricht einer Elementfunktion in C++ oder einer Funktion oder Prozedur in Ada. Welches Verhalten Sie einem Objekt zuordnen, richtet sich nach der Rolle, die das Objekt in Anwendungsfallrealisierungen hat.

Parameter

In der Spezifikation einer Operation sind die Parameter formale Parameter. Jeder Parameter hat einen Namen und einen Typ. Sie können Syntax und Semantik der Implementierungssprache verwenden, um die Operationen und ihre Parameter anzugeben, so dass sie bereits in der Implementierungssprache enthalten sind, wenn mit der Codierung begonnen wird.

Beispiel:

Im System der Recycling-Maschine verfolgen die Objekte einer Klasse Annahmestation, wie viele Pfandartikel eines bestimmten Typs ein Kunde eingeworfen hat. Das Verhalten eines Objekts Annahmestation sieht so aus, dass die Anzahl der zurückgegebenen Objekte hochgezählt wird. Die Operation insertItem, die eine Referenz auf den eingeworfenen Artikel erhält, erfüllt diesen Zweck.

Im Begleittext beschriebene Abbildung

Verwenden Sie die Syntax und die Semantik der Implementierungssprache für die Angabe von Operationen.

Klassenoperationen

Eine Operation bezeichnet fast immer das Objektverhalten. Eine Operation kann auch das Verhalten einer Klasse bezeichnen. In diesem Fall handelt es sich um eine Klassenoperation. Eine solche Klassenoperation kann in UML durch Typeinordnung der Operation modelliert werden.

Sichtbarkeit von Operationen

Die folgenden Sichtbarkeitsoptionen für Operationen sind möglich:

  • Public (Öffentlich): Die Operation ist auch für andere Modellelemente abgesehen von der Klasse sichtbar.
  • Protected (Geschützt): Die Operation ist nur für die Klasse selbst, ihre Unterklassen und für so genannte Friends der Klasse (sprachenabhängig) sichtbar.
  • Private (Privat): Die Operation ist nur für die Klasse selbst und für so genannte Friends der Klasse sichtbar.
  • Implementation (Implementierung): Die Operation ist nur innerhalb der Klasse sichtbar.

Die Sichtbarkeitsoption Public sollte sparsam und nur dann verwendet werden, wenn eine Operation von einer anderen Klasse benötigt wird.

Die Sichtbarkeitsoption Protected sollte die Standardeinstellung sein. Sie schützt die Operation vor der Verwendung durch externe Klassen, was eine lose Verbindung und Kapselung von Verhalten begünstigt.

Die Sichtbarkeitsoption Private sollte verwendet werden, wenn Sie verhindern möchten, dass Unterklassen die Operation erben. Auf diese Weise können Unterklassen von der Superklasse entkoppelt werden. Außerdem verringern Sie damit den Bedarf, nicht verwendete geerbte Operationen entfernen und ausschließen zu müssen.

Die Sichtbarkeitsoption Implementation ist die restriktivste. Sie wird verwendet, wenn nur die Klasse selbst in der Lage ist, die Operation zu verwenden. Sie ist eine Variante der Sichtbarkeitsoption Private, die in den meisten Fällen ausreichend ist.

Zustände

Ein Objekt kann in Abhängigkeit von seinem Zustand unterschiedlich auf eine bestimmte Nachricht reagieren. Das zustandsabhängige Verhalten eines Objekts wird mit einem zugeordneten Zustandsdiagramm definiert. Für jeden Zustand, den ein Objekt annehmen kann, beschreibt das Zustandsdiagramm, welche Nachrichten das Objekt empfangen kann, welche Operationen ausgeführt werden und welchen Zustand das Objekt danach hat. Weitere Informationen hierzu finden Sie in Technik: Zustandsdiagramm.

Kollaborationen

Eine Kollaboration ist eine dynamische Gruppe von Objektinteraktionen, in der mehrere Objekte miteinander kommunizieren, indem sie einander Nachrichten senden. Das Senden einer Nachricht ist in Smalltalk eine direkte Operation. In Ada wird zum Senden einer Nachricht ein Unterprogramm aufgerufen. Eine Nachricht wird an ein empfangendes Objekt gesendet und ruft eine Operation im Objekt auf. Die Nachricht enthält den Namen der auszuführenden Operation und die erforderlichen Parameter. Wenn Nachrichten gesendet werden, werden tatsächliche Parameter (Werte für die Formalparameter) für alle Parameter bereitgestellt.

Die Nachrichtenübertragungen zwischen Objekten in einer Anwendungsfallrealisierung und Steuerungsfokus der Objekte, dem die Objekte beim Aufruf von Operationen folgen, werden in einem Interaktionsdiagramm beschrieben. Informationen zu diesen Diagrammen finden Sie in Technik: Ablaufdiagramm und Technik: Kommunikationsdiagramm.

Ein Attribut ist eine benannte Eigenschaft eines Objekts. Der Attributname ist ein Substantiv, das die Rolle des Attributs in Relation zum Objekt beschreibt. Ein Attribut kann einen Anfangswert haben, wenn das Objekt erstellt wird.

Sie sollten Attribute nur modellieren, wenn damit ein Objekt verständlicher wird. Modellieren Sie die Eigenschaft eines Objekts nur dann als Attribut, wenn es sich ausschließlich um eine Eigenschaft dieses Objekts handelt. Andernfalls sollten Sie die Eigenschaft mit einer Assoziations- oder Aggregationsbeziehung zu einer Klasse modellieren, deren Objekte die Eigenschaft darstellen.

Beispiel:

Im Begleittext beschriebenes Diagramm

Ein Beispiel, das zeigt, wie ein Attribut modelliert wird. Jedes Mitglied einer Familie hat einen Namen und eine Adresse. Im Beispiel werden die Attribute Mein Name und Privatadresse der Typen Name und Adresse verwendet.

Im Begleittext beschriebenes Diagramm

In diesem Beispiel wird anstelle eines Attributs eine Assoziation verwendet. Die Eigenschaft Mein Name ist wahrscheinlich für jedes Mitglied einer Familie eindeutig. Deshalb kann sie als Attribut des Attributtyps Name modelliert werden. Eine Adresse hingegen ist für alle Familienmitglieder dieselbe. Deshalb wird sie am besten mit einer Assoziation zwischen der Klasse Familienmitglied und der Klasse Adresse modelliert.

Es ist nicht immer einfach, sofort zu entscheiden, ob ein Konzept als separates Objekt oder als ein Attribut eines anderen Objekts modelliert werden sollte. Unnötige Objekte im Objektmodell führen zu unnötiger Dokumentation und unnötigem Entwicklungsaufwand. Deshalb müssen Sie bestimmte Kriterien aufstellen, um zu bestimmen, wie wichtig ein Konzept für das System ist.

  • Zugriffsmöglichkeit. Was Ihre Wahl zwischen Objekt und Attribut steuert, ist nicht die Bedeutung des Konzepts im wahren Leben, sondern der Bedarf, im Anwendungsfall darauf zugreifen zu können. Wenn sehr häufig auf die Einheit zugegriffen wird, modellieren Sie sie als Objekt.
  • Trennung während der Ausführung. Modellieren Sie Konzepte, die während der Ausführung von Anwendungsfällen gesondert behandelt werden, als Objekte.
  • Bindungen zu anderen Konzepten. Modellieren Sie Konzepte, die eng an bestimmte andere Konzepte gebunden sind und nie gesondert genutzt werden, sondern immer über ein Objekt, als Attribut des Objekts.
  • Ansprüche aus Beziehungen. Wenn Sie aus irgendeinem Grund eine Einheit aus zwei Richtungen in Beziehung bringen müssen, untersuchen Sie die Einheit erneut, um festzustellen, ob sie eigentlich ein gesondertes Objekt sein sollte. Es ist nicht möglich, dass zwei Objekte dieselbe Instanz eines Attributtyps zuordnen.
  • Häufigkeit des Vorkommens. Wenn eine Einheit nur in einem Anwendungsfall vorkommt, modellieren Sie sie nicht als Objekt. Modellieren Sie sie stattdessen als Attribut des Objekts, das das fragliche Verhalten erbringt, oder erwähnen Sie sie einfach in der Beschreibung des betroffnen Objekts.
  • Komplexität. Wenn ein Objekt aufgrund seiner Attribute zu komplex wird, können Sie unter Umständen einige Attribute in gesonderte Objekte extrahieren. Gehen Sie dabei sorgfältig vor, um am Ende nicht zu viele Objekte zu haben. Andererseits können die Einheiten sehr direkt sein. Als Attribute klassifiziert werden beispielsweise (1) Einheiten, die einfach genug sind, um direkt von primitiven Typen in der Implementierungssprache, z. B. Integern in C++, unterstützt zu werden, und (2) Einheiten, die einfach genug sind, um mit den anwendungsunabhängigen Komponenten der Implementierungsumgebung, z. B. String in C++ und Smalltalk-80, implementiert zu werden.

Ein Konzept kann für unterschiedliche Systeme unterschiedlich modelliert werden. In einem System kann das Konzept so wichtig sein, dass es als Objekt modelliert wird, und in einem anderen System kann es von eher untergeordneter Bedeutung sein, und deshalb modellieren Sie es als Attribut eines Objekts.

Beispiel:

Sie entwickeln beispielsweise für ein eine Fluggesellschaft ein System, das Abflüge verwaltet.

Im Begleittext beschriebenes Diagramm

Ein System, das Abflüge verwaltet. Angenommen, das Personal an einem Flugplatz möchte ein System, das Abflüge unterstützt. Für jeden Abflug müssen Sie die Abflugzeit, die Fluggesellschaft und den Zielort definieren. Sie können dieses System als Objekt einer Klasse Abflug mit den Attributen Abflugzeit, Fluggesellschaft und Zielort modellieren.

Wenn das System stattdessen für ein Reisebüro entwickelt wird, sieht die Situation etwas anders aus.

Im Begleittext beschriebenes Diagramm

Zielorte bilden ein eigenes Objekt Zielort.

Die Abflugzeit, die Fluggesellschaft und der Zielort werden natürlich weiterhin benötigt. Allerdings gibt es noch weitere Anforderungen, da ein Reisebüro daran interessiert ist, eine Abflugzeit mit einem bestimmten Zielort zu finden. Sie müssen deshalb ein gesondertes Objekt für Zielort erstellen. Die Objekte Abflugzeit und Zielort müssen einander natürlich kennen, was durch eine Assoziation zwischen ihren Klassen ermöglicht wird.

Das Argument für die Bedeutung bestimmter Konzepte gilt auch für die Bestimmung, welche Attribute in einer Klasse definiert werden sollten. Die Klasse Auto definiert zweifellos andere Attribute, wenn ihre Objekte zu einem Registrierungssystem für Kraftfahrzeuge gehört, als wenn ihre Objekt zu einem Fertigungssysteme für Automobile gehören.

Abschließend lässt sich sagen, dass die Regeln für die Darstellung von Objekten als Objekte oder als Attribute nicht absolut sind. Theoretisch können Sie alles als Objekt modellieren, aber das ist mühsam. Eine einfache Faustregel ist die, ein Objekt als etwas zu betrachten, das zu irgendeinem Zeitpunkt unabhängig von anderen Objekten verwendet wird. Außerdem müssen Sie nicht jede Objekteigenschaft als Attribut modellieren, sondern nur die Eigenschaften, die erforderlich sind, um das Objekt zu verstehen. Modellieren Sie keine Details, die so implementierungsspezifisch sind, dass sie besser vom Implementierer behandelt werden sollten.

Klassenattribute

Ein Attribut bezeichnet fast immer Objekteigenschaften. Ein Attribut kann auch Eigenschaften einer Klasse bezeichnen. In diesem Fall handelt es sich um ein Klassenattribut. Eine solche Klassenoperation kann in UML durch Typeinordnung des Attributs modelliert werden.

Externe Einheiten mit Attributen modellieren

Ein Objekt kann etwas kapseln, dessen Wert sich ändern kann, ohne dass das Objekt ein Verhalten aufweist. Es kann sich um etwas handeln, das in der Tat eine externe Einheit ist, aber das nicht als Akteur modelliert wurde. Es können beispielsweise Systemgrenzen so ausgewählt worden sein, dass irgendeine Form von Sensor dazwischen liegt. Der Sensor kann dann in einem Objekt gekapselt werden, so dass der Wert, den der Sensor misst, ein Attribut darstellt. Dieser Wert kann sich kontinuierlich oder in bestimmten Intervallen ändern, ohne dass das Objekt von einem anderen Objekt im System beeinflusst wird.

Beispiel:

Sie können ein Thermometer als Objekt modellieren. Das Objekt hat ein Attribut, das die Temperatur darstellt und seinen Wert ändert, wenn sich die Temperatur der Umgebung ändert. Andere Objekte können die aktuelle Temperatur abfragen, indem sie eine Operation mit dem Thermometerobjekt ausführen.

Im Begleittext beschriebenes Diagramm

Der Wert des Attributs Temperatur im Objekt Thermometer ändert sich spontan.

Sie können einen gekapselten Wert, der sich auf diese Weise ändert, trotzdem als gewöhnliches Attribut modellieren, sollten aber in der Klasse des Objekts beschreiben, dass sich das Attribut spontan ändert.

Sichtbarkeit von Attributen

Die folgenden Sichtbarkeitsoptionen für Attribute sind möglich:

  • Public (Öffentlich): Das Attribut ist innerhalb und außerhalb des Pakets, das die Klasse enthält, sichtbar.
  • Protected (Geschützt): Das Attribut ist nur für die Klasse selbst, ihre Unterklassen und für so genannte Friends der Klasse (sprachenabhängig) sichtbar.
  • Private (Privat): Das Attribut ist nur für die Klasse selbst und für so genannte Friends der Klasse sichtbar.
  • Implementation (Implementierung): Das Attribut ist nur für die Klasse selbst sichtbar.

Die Sichtbarkeitsoption Public sollte sparsam und nur dann verwendet werden, wenn ein Attribut direkt für eine andere Klasse zugänglich ist. Letztendlich ist die Sichtbarkeitsoption "Public" eine Kurzschreibweise für Folgendes: Die Sichtbarkeit des Attributs wird mit "Protected", "Private" oder "Implementation" festgelegt, und es werden Operationen mit der Sichtbarkeitsoption "Public" definiert, die den Wert des Attributs lesen oder verändern können. Attribute mit der Sichtbarkeitsoption "Public" können als Deklaration für einen Codegenerator verwendet werden, der diese Lese- und Änderungsoperationen (get/set) automatisch generiert. Auf diese Weise kann Zeit bei der Klassendefinition eingespart werden.

Die Sichtbarkeitsoption Protected sollte die Standardeinstellung sein. Sie schützt das Attribut vor der Verwendung durch externe Klassen, was eine lose Verbindung und Kapselung von Verhalten begünstigt.

Die Sichtbarkeitsoption Private sollte verwendet werden, wenn Sie verhindern möchten, dass Unterklassen das Attribut erben. Auf diese Weise können Unterklassen von der Superklasse entkoppelt werden. Außerdem verringern Sie damit den Bedarf, nicht verwendete geerbte Attribute entfernen und ausschließen zu müssen.

Die Sichtbarkeitsoption Implementation ist die restriktivste. Sie wird verwendet, wenn nur die Klasse selbst in der Lage ist, das Attribut zu verwenden. Sie ist eine Variante der Sichtbarkeitsoption Private, die in den meisten Fällen ausreichend ist.

Interne Struktur

Einige Klassen stellen komplexe Abstraktionen dar und haben eine komplexe Struktur. Bei der Modellierung einer Klasse möchte der Designer vielleicht die internen teilnehmenden Elemente und ihre Beziehungen darstellen, um sicherzustellen, dass der Implementierer die Kollaborationen innerhalb dieser Klasse entsprechend implementiert.

In UML 2.0 sind Klassen als strukturierte Klassen definiert, die eine interne Struktur und Ports haben können. Klassen können in verbundene Teile zerlegt werden, die dann noch weiter zerlegt werden können. Eine Klasse kann gekapselt werden, indem eingehende Kommunikation über Ports geleitet werden, die deklarierten Schnittstellen entsprechen.

Zusätzlich zu Klassendiagrammen, die die Klassenbeziehungen (z. B. Assoziationen, Kompositionen und Aggregationen) und Attribute darstellen, kann der Designer ein zusammengesetztes Strukturdiagramm verwenden. Dieses Diagramm gibt dem Designer einen Mechanismus an die Hand, mit dem er zeigen kann, wie Instanzen der internen Parteien ihre Rollen in einer Instanz einer bestimmten Klasse spielen.

Weitere Informationen zu diesem Thema und Beispiele zu zusammengesetzten Strukturdiagrammen finden Sie in Konzept: Strukturierte Klasse.