is-Logo Objektorientierte Analyse (OOA)
Klassenbeziehungen II

S. Spolwig

[Home | OOP | OOA]

page_down

Beziehungen zwischen Klassen für Fortgeschrittene

1.    Vererbungsbeziehungen
2.    Referenz- oder Nutzungsbeziehungen
2.1 
Aggregation
2.2 
Assoziation
3.    Kardinalitäten
4.   
Hilfe - welche Beziehung nehme ich?
5.   Typische Anwendungsmuster (design pattern)

6.  
Hinweise zur Implementation

Eine prinzipielle OO-Sichtweise beschreibt das Verhältnis zwischen zwei aktiven Objekten als eine typische Client-Server Situation. Wenn ein Objekt irgendeine Aktion nicht aus dem eigenen Verhaltensrepertoire erfüllen kann, dann fordert es als Klient mit einer Botschaft von einem anderen Objekt (Server) einen Dienst oder eine Leistung an. Realisiert wird die Klient - Server Beziehung über eine der Referenzbeziehungen.

Aus der Fülle der Beziehungssituationen sind folgende drei von besonderer Bedeutung: Vererbung, Aggregation und Assoziation

1. Vererbungsbeziehungen (Spezialisierung / Generalisierung)

Kinder haben Eltern. Sie erben von den Eltern Eigenschaften wie Haarfarbe, Hautfarbe und auch oft Verhaltensweisen. Diese Beziehung lässt sich abbilden und ist ein besonderes, wichtiges Merkmal der OOP.

Beispiel: In einem Betrieb gibt es verschiedene Arten von Mitarbeitern.

Alle drei haben die gleichen Personenattribute wie Name, Vorname usw., die sich quasi überdecken. Man spricht daher auch von einer Überdeckungsbeziehung. Ein Arbeiter ist eine Art von Mitarbeiter ('IS-KIND-OF' oder 'IS-A'), der aber eine besondere Form der Lohnberechnung hat.

Sie haben aber auch unterschiedliche, spezielle Attribute wie Arbeitsstunden beim Arbeiter und unterschiedliche Methoden der Gehaltsberechnung. Die Vererbungsbeziehung ist damit eine Spezialisierung vom Allgemeinen (Gemeinsamen) zum Besonderen, wie Sie auch bei der wissenschaftlichen Klassifikation angewandt wird. Betrachtet man eine Vererbungsbeziehung in der entgegengesetzten Richtung, in dem man aus verschiedenen Klassen gemeinsame Merkmale extrahiert und in eine Oberklasse auslagert, spricht man von einer Generalisierung. Eine Vererbung ist also eine Strukturbeziehung zwischen Klassen, die konstitutiv ist für alle abgeleiteten Exemplare.

Programmtechnisch bedeutet das: Mitarbeiter ist die Oberklasse. Angestellter und Arbeiter sind Unterklassen (Erben) von Mitarbeiter. Arbeiter erbt alle Attribute und Methoden von TMitarbeiter (Name, Vorname, Entgelt, Zeigen usw.) und fügt Stunden und LohnBerechnen als spezielle hinzu. Da intern nur ein Verweis auf den Code in der Oberklasse benutzt wird, sind die geerbten Attribute und Methoden sofort verfügbar und werden nicht noch einmal aufgeführt. (Wenn man es doch tut, werden die geerbten 'überdeckt', d.h. außer Kraft gesetzt und es gelten dann die eigenen!) 

Mehrfachvererbung

Bei der eleganten Idee der Vererbung scheint diese Möglichkeit bestechend. Man erbt aus zwei oder mehr Oberklassen, was man für eine neue Unterklasse braucht. Was manche Biologen und Genetiker noch heimlich in ihrem Labors probieren ist in OOP  gelöst. Die Kreuzung zwischen Delphin und Mensch ('Homophin') für die nächste Olympiade ist ein Kinderspiel .

Nun zu einem ernsthaften Beispiel:



Einige OO-Sprachen (C++, Eiffel) erlauben die Mehrfachvererbung, JAVA nur indirekt mit einem Kunstgriff (abstrakte Oberklassen als Interfaces), jedoch SMALLTALK und Object-Pascal z. B. nicht. Dafür gibt es eine Reihe guter Gründe. Bei Namensgleichheit von Attributen oder Methoden in den Oberklassen gibt es einen Konflikt, welches gelten soll. Das lässt sich zwar u. U. noch durch sorgfältige Programmierung beheben. Gefährlicher noch könnte es sich auswirken, wenn Kreditvertrag als eine Bibliotheksklasse ein privates (nicht dokumentiertes) Attribut 'Datum' zur Berechnung der Laufzeit enthält.

Transformation von Mehrfachvererbung

  1. Auflösung in ein Kette von Einzelvererbungen

  2. Auflösung durch Aggregation

Die gemeinsamen Eigenschaften der Oberklasse 'Kreditvertrag' werden ausgelagert (Delegation) und mit einer Aggregationsbeziehung wieder eingebunden.

 

2. Referenz- oder Nutzungsbeziehungen

Während bei der Vererbung Klassen verknüpft sind, besteht hier eine konkrete statische Beziehung zwischen zwei beteiligten Objekten (!), die als Beziehung zwischen den Klassen der Objekte spezifiziert und realisiert wird. (Es hat sich aber eingebürgert, die Beziehungsgraphen zwischen den Klassen zu zeichnen.) Die Art der Beziehung ergibt sich aus semantischen Nähe der beteiligten Exemplare, die örtlich oder zeitlich enger oder loser an einander gebunden sind.

Assoziationen sind von Hause aus bidirektional, werden aber häufig nur in einer bestimmten Richtung (des Zugriffs)  benötigt und implementiert. Wenn der Zugriff nur auf ein bestimmtes der beteiligten Objekt erfolgen darf, spricht man von einer gerichteten Beziehung

Im Gegensatz zum ERM sind beim objektorientierten Modell keine Referenzattribute oder Fremdschlüssel notwendig, es sei denn sie sind aus dem Fachkonzept heraus erforderlich.

. Des weiteren ist die Wahl der Assoziation zu unterscheiden nach:

  • Kardinalitäten (0,1,viele) zwischen den Objekten.

  • Muss-Beziehung: Wenn das erste Objekt erzeugt wird, muss auch das zweite vorhanden sein und auch die Beziehung zwischen beiden (Kardinalität 1..*)

  • Kann-Beziehung: Die Beziehung kann zur Laufzeit aufgebaut werden (minimale Kardinalität = 0) .

 

2.1  Die Aggregation

Aggregation ist der Sonderfall einer gerichteten Assoziation (s.u.). Sie drückt ein starkes semantisches Verhältnis von zwei an sich selbständigen Objekten aus, von denen eines Teil des anderen ist ('IS-PART-OF').

2.1.1  Die echte Aggregation (Komposition)

  • Komponenten sind vom Aggregat existenzabhängig
    – Erzeugung des Aggregats erzeugt auch die Komponenten
    – Löschung des Aggregats löscht auch die Komponenten

  • Die echte Aggregation übernimmt die dynamische Weiterleitung von Botschaften an die Komponenten  z. B. Aggregat.Create stößt Komponente.Create an.

Beispiel: Der Motor ist Teil eines Autos

Motor als komplexes Objekt wird dem Autoobjekt hinzugefügt (aggregiert) und damit zu einem Attribut von TAuto. Es wird daher als eingebundenes Komponentenobjekt bezeichnet. Im Normalfall ist ein Auto erst dann fertig, wenn der Motor eingebaut ist, d. h. der Motor muss beim Erzeugen des Autos automatisch miterzeugt werden. Beim Verschrotten wird der Motor mit verschrottet.

2.1.2  Die einfache Aggregation

  • Aggregat und Komponenten sind nicht existenzabhängig
    – Komponente kann (zusätzlich) einem anderen Aggregat derselben Klasse zugeordnet sein
    – Komponente kann (zusätzlich) einer anderen Klasse zugeordnet sein
    – Komponente existiert unabhängig vom Aggregat

    z. B. Aggregat.Loeschen bewirkt nicht Löschen der Komponenten und Komponente kann ohne Aggregat weiter existieren

Für das Autobeispiel bedeutet das, dass der Motor vor dem Einbau schon existierte und er vor dem Verschrotten ausgebaut wird, um als Austauschmotor für ein anderes Auto gebraucht zu werden.

Beispiele für Aggregationen

Eine klassische Anwendung der Aggregation sind die grafischen Benutzeroberflächen (GUI), die aus Buttons, Editfeldern und anderen Komponenten zusammengesetzt sind. Weitere typische Situationen für Aggregation sind:

  • Das Ganze und seine Teile (Auto und Motor)

  • der Behälter und sein Inhalt (Cockpit und Pilot)

  • die Kollektion und ihre Elemente (Kundenliste und Kunde)

  • Invariante Konfigurationen (Ehe: wird ein Mitglied entfernt, ist die Ehe zerstört)

Letztlich kann man zwei Arten der Aggregation finden:

  • physische Aggregation:  Das Analyseobjekt besteht aus Teilen. Der Motor ist Teil eines Autos (Komposition).

  • logische Aggregation: Begriffliche Objekte werden als ein Teil angesehen. Die Adresse gehört zu einer Person.

Grenzfälle

Häufig lässt sich nur schwierig festlegen, ob eine Aggregation oder Assoziation vorliegt. In den 90er Jahren des vorigen Jahrhunderts wurden viele kluge Kapitel über das Wesen der Aggregation und die Grenzfälle geschrieben. Im Extremfall wird sogar auf die Aggregation verzichtet. Das führt aber zu einer Verarmung des semantischen Verständnisses eines Systems. Im Zweifel sollte man eine Assoziation beschreiben.

2.2  Assoziation

Sie drückt das Verhältnis von zwei völlig selbständigen Objekten

aus, die auf der gleichen Abstraktionsebene stehen und eigentlich nichts miteinander zu tun haben, aber unter bestimmten Gesichtspunkten in eine lose Kennt-Beziehung ('KNOWS') gebracht werden können.

Beispiel: Kunde Meier erteilt Auftrag1 zur Softwareerstellung

Kunde Meier kann einen, mehrere oder keinen Auftrag erteilt haben. Die Verbindung wird also erst dann aufgebaut, wenn der Auftrag erteilt wird und kann gelöscht werden, wenn das Produkt geliefert wurde. Die Assoziation kann dadurch hergesellt werden, dass in Kunde eine Referenz auf das Auftragsobjekt eingesetzt wird.

Qualifizierte Assoziation

Bei Objekten, die Beziehungen zu einer Sammlung von Objekten haben (Artikelliste) lässt sich eine Assoziation auch dadurch aufbauen, dass die Referenz auf ein qualifizierendes Attribut (Schlüssel) zeigt.

Beispiel: Einem flotten Kellner genügt es, wenn er die Artikelnummer aus der Speisekarte in die Bestellung aufnimmt.


Die qualifizierte Assoziation ist die OOA-Umsetzung von Look-Up-Methoden wie  sie bei Datenbanken mit Hilfe von Schlüsseln realisiert werden.

 

Assoziation mit Linkobjekt

Bei einer m : n-Beziehung wird dazu eine neue Klasse gebildet, deren Exemplare (Linkobjekt) die aktuelle Beziehung realisiert.

(Kurznotation in UML)

In der Verfeinerung wird man die Link-Klasse einführen, die dann leider wiederum zwei Beziehungen mit den Ausgangsklassen hat, die unterschiedlich gestaltet werden können.

Für die Link-Klasse gibt es also mehrere Möglichkeiten der Kombination und Implementation, die auch je nach verwendeter Programmiersprache unterschiedlich realisiert werden können
(s. Implementierungshinweise), z. B.: 

  • als Aggregation oder Assoziation in der dritten Klasse (wie eine Beziehung im ERM)

    Beispiel: Elli Pirelli bestellt den blauen Mercedes.

    Die Kundenbestellung "besteht aus" Kunde und Auto.

     

  • mit Vererbung in einer dritten Klasse, wenn es sinnvoll erscheint

Beispiel: Rudi Ratlos mietet einen Opel aus der Mietwagenflotte.

Für die Assoziation von zwei Objekten (Kunde - Auto) gibt es Lösungen, die auf das dritte neu gebildete Link-Objekt verzichten (s.o.). Die Einführung eines Linkobjekts hat aber den Vorteil, dass beide Objekte selbständig bleiben und daher auch von anderen Objekten einzeln angesprochen werden können. Außerdem ist die Lösung immer dann notwendig, wenn die Beziehung selbst Attribute speichern muss; z. B. Übernahme- und Abgabetermin.
 

3.  Kardinalitäten

  Die Kardinalität (K1, K2) legt fest, wie viele Exemplare aus K2
    einem Exemplar aus K1 zugeordnet werden können.

  • Dabei werden drei Grundtypen unterschieden:

    1  : 1
    -  1  : n
    -  m : n

  • In dieser Schreibweise gibt die Kardinalität nur an, wie viele Exemplare maximal miteinander verbunden sein können.

Andere Notationen (UML) sind:
1     : genau eine
0,1  : konditionell, keine oder eine
*     : multiple, keine Einschränkung
0..* :  multiple
1..* : mindestens eine

  • Methode der Festlegung und Notation:

Die Kardinalität wird jeweils an der gegenüber liegenden Klasse notiert,
z. B. 1 Exemplar aus Klasse2  kann nur mit genau 1 aus Klasse1 Beziehungen haben.

Weitere Beispiele s. Entity Relationship Model / Konnektivität

 

4.  Hilfe - welche Beziehung nehme ich?

Die Antwort ist ebenso einfach wie unbefriedigend:

  Die richtige Beziehung ist die, die das Verhältnis der beteiligten Objekte
            im Kontext des Fachkonzeptes
am besten abbildet.

Wenn die Beziehung nicht gleich ins Auge springt, kann ein Blick auf Design pattern weiterhelfen. Leider gibt es  keine zementierten einfachen Lösungen. Das möge ein Beispiel verdeutlichen.

Der Gast bestellt aus der Speisekarte die Nr. 14 - Pizza Marinara - 11.50 DM. Der flotte Kellner notiert '1 x 14'. Ein trotteliger schreibt vorsichtiger Weise  '14 - Pizza Marinara - 11.50' . Die Bestellung lässt sich entsprechend entweder durch eine Referenz auf das komplette Artikel-Objekt oder nur durch die qualifizierte Assoziation auf die Artikel-Nummer realisieren, was zunächst als die schmalere Variante erscheint.

Die Rechnung dazu ist im Prinzip nichts anderes als die Bestellung des Artikels ergänzt um ein paar Daten und Berechnungen. Während die Bestellung flüchtig ist und nach der Rechnungslegung gelöscht wird, verlangen die handels- und steuerrechtlichen Vorschriften, dass Rechnungen 10 Jahre aufbewahrt (gespeichert) werden müssen. Hier reicht also nicht, die Referenz auf die Artikelnummer (schon deshalb nicht, weil nach einiger Zeit eine neue Speisekarte mit der Nummer 14 'Spaghetti' ausweist), sondern die Rechnung muss die kompletten Artikelattribute enthalten. Man wird also eine Komposition wählen.

5.   Typische Anwendungsmuster   ==> (design pattern)

6.   Hinweise zur Implementation ==> Delphi

------------------
Literatur

Balzert, H.:
Lehrbuch der Software-Technik (2 Bände), Spektrum Akademischer Verlag (1996)
Oestereich, B:
Objektorientierte Softwareentwicklung. Analyse und Design mit der Unified Modeling Language, Oldenbourg (1999)



©  05. Oktober 2008     Siegfried Spolwig

page_top