Modellierung mit
UML
Loading

4.3 Logik der Objektdiagramme

Dieser und der folgende Abschnitt führen eine wesentliche Erweiterung der Objektdiagramme ein, die ihren methodischen Einsatz erleichtert. Dafür werden Operatoren aus der OCL verwendet, die es erlauben, genauer festzulegen, wann Objektdiagramme gültig sind und wie sie miteinander verbunden werden. Durch die Integration der Objektdiagramme mit den Operationen der OCL entsteht eine „Logik der Objektdiagramme“. Dadurch können Objektdiagramme als Aussagen in die OCL eingebunden, aber auch auf verschiedene Weisen miteinander kombiniert werden.

4.3.1 Namen für ein Diagramm

Um Objektdiagramme in OCL-Bedingungen einbinden zu können, geben wir den Diagrammen Namen. Abbildung 4.18 zeigt das Objektdiagramm mit dem Namen BidTime1.

Lädt...
Abbildung 4.18: Objektdiagramm BidTime1

Auf dieses Diagramm kann in der OCL als Aussage der Form OD.BidTime1 Bezug genommen werden. So ist es möglich, zusätzliche Bedingungen, die in einer durch BidTime1 beschriebenen Objektstruktur gelten müssen, festzulegen:

OD.bidTime1 &&
  timePol.start.lessThan(bid.biddingTime) &&
  bid.biddingTime.lessThan(timePol.finish)

Um die gewünschte Wirkung der Aussage zu erzielen ist allerdings sorgfältig auf die im Objektdiagramm und den OCL-Bedingungen verwendeten Namen und deren Bindung zu achten. Die gewünschte Aussage ist von der Form: „Immer wenn eine Objektstruktur wie in Objektdiagramm BidTime1 auftritt, dann gelten zusätzlich die Bedingungen …“. Diese Aussage ist in ihrer Natur eine Invariante, die teilweise durch das Objektdiagramm graphisch spezifiziert ist. Obige OCL-Aussage leistet das Gewünschte nicht, da die Quantifizierung der freien Variablen unklar ist.

4.3.2 Bindung von Objektnamen

In Objektdiagrammen werden meist mehrere Objekte namentlich genannt, auf die in den OCL-Bedingungen Bezug genommen werden kann. Die Bindungsbereiche der Namen a, timePol und bid im gezeigten Objektdiagramm BidTime1 sind deshalb außerhalb des Objektdiagramms festzulegen. Obige OCL-Bedingung kann damit in einen vollständigen Kontext eingebettet werden:

context Auction a, ConstantTimingPolicy timePol,
  BidMessage bid inv BidTime1A:
  OD.bidTime1 implies
    timePol.start.lessThan(bid.biddingTime) &&
    bid.biddingTime.lessThan(timePol.finish)

Wird ein Objektdiagramm in einer OCL-Bedingung verwendet, so ist darauf zu achten, dass alle im Objektdiagramm verwendeten Namen in der OCL-Bedingung eingeführt werden, die Bedingung also geschlossen ist. Die Verwendung des Quantors zur Bindung von Objektnamen erlaubt einen flexiblen Einsatz der Objektdiagramme. So kann mit der folgenden Aussage gefordert werden, dass in jeder Auktion, die bereits begonnen hat, eine Willkommensnachricht versandt wurde. Dabei werden die zwei Objektdiagramme aus Abbildung 4.19 verwendet, von denen Welcome1A die Voraussetzung für die Forderung Welcome1B darstellt.

Lädt...
Abbildung 4.19: Objektdiagramme für die Willkommensnachricht

inv Welcome1:
  forall Auction a, TimingPolicy timePol:
    OD.Welcome1A implies
      exists Message welcome: OD.Welcome1B

Im Gegensatz zum ersten Beispiel BidTime1A wurden hier nicht alle Objekte der Objektdiagramme durch eine Allquantifizierung gebunden. Deshalb ist auch der Einsatz beider Diagramme unterschiedlich. Die Aussage lautet: „Wenn Objekte a und timePol existieren und dem Objektdiagramm Welcome1A genügen, dann existiert Objekt welcome und es gelten alle im Objektdiagramm Welcome1B formulierten Eigenschaften“. Dabei müssen die Einzelheiten des ersten Teildiagramms nicht wiederholt werden. Es ist ausreichend, die neuen relevanten Eigenschaften (also die Existenz des Links mit dem Qualifikator 0) zu fordern.

Bei der Formulierung der Bedingung Welcome1 wurde als Voraussetzung angegeben, dass der Status der Auktion auf geöffnet (RUNNING) gesetzt ist. Ist die Auktion geschlossen, so ist über die Existenz einer Willkommensnachricht nichts ausgesagt.

Es ist beachtenswert, dass die unter Benutzung von zwei Objektstrukturen getroffene Aussage keine zeitlichen Implikationen hat, sondern nur über einem Snapshot des Systems interpretiert wird. Das verwendete implies führt zu einer Aussage der Form: „Ist der Status RUNNING, dann existiert eine Willkommensnachricht mit Index 0 in der Auktion“. Eine schärfere, aber andere Aussage wäre: „Wenn der Zustand auf RUNNING gesetzt wird, dann ist eine Willkommensnachricht zu versenden“. Diese ist allerdings nicht als Invariante, sondern als Methodenspezifikation (einer noch nicht benannten Methode zur Eröffnung von Auktionen) zu spezifizieren, denn diese schärfere Aussage beinhaltet eine zeitliche Implikation. Die Aussage Welcome1 ist demgegenüber echt schwächer, denn sie erlaubt Implementierungsalternativen, indem zum Beispiel die Willkommensnachricht bereits mit der Auktion angelegt wird.

4.3.3 Integration von Objektdiagramm und OCL

Grundsätzlich können strukturelle Eigenschaften von Objektdiagrammen und die darin enthaltenen Attributwerte auch durch die OCL direkt dargestellt werden, denn es lassen sich alle Konstrukte eines Objektdiagramms in OCL-Aussagen umsetzen. Deshalb besteht die Wahlmöglichkeit bei den Mitteln zur Darstellung von Eigenschaften. Beispielsweise kann die Aussage Welcome1 als OCL-Formel wie folgt dargestellt werden:

inv Welcome2:
  forall Auction a, TimingPolicy timePol:
    (Object)a != timePol &&
    a.timePol == timePol &&
    timePol.status == TimingPolicy.RUNNING
  implies
    exists Message welcome:
      (Object)a != welcome&&
      a.message[0] == welcome

Die paarweise Unterscheidung von Objekten eines Objektdiagramms ist in der OCL durch explizite Ungleichungen sicherzustellen. Dies kann mit Ungleichungen der Form a != timePol erreicht werden.4

Die Praxis zeigt, dass umfangreiche Spezifikationen von Objektstrukturen nur mit der OCL allein schnell unübersichtlich werden. Demgegenüber sind Objektdiagramme nur beschränkt aussagekräftig. Die Synergie beider Notationen erlaubt eine mächtige und kompakte Darstellung von Objektstrukturen.

4.3.4 Anonyme Objekte

Die Verwendung expliziter Objektnamen in einem Objektdiagramm erlaubt den Zugriff auf diese Objekte von außerhalb des Diagramms. Anonyme Objekte zeigen zwar, dass derartige Objekte existieren müssen, erlauben aber nur indirekten Zugriff über die Links zu diesen Objekten. Der Einsatz eines anonymen Objekts kann bei einer Transformation in OCL durch eine Existenzquantifizierung erklärt werden. Tatsächlich ist der Einsatz anonymer Objekte hilfreich, weil dadurch der Kontext eines Objektdiagramms geringer wird. Abbildung 4.20 zeigt anonymisierte Versionen der Objektdiagramme aus Abbildung 4.19. Dadurch können in der folgenden, zu Welcome1äquivalenten Aussage zwei Quantifizierungen weggelassen werden6

Lädt...
Abbildung 4.20: Anonymisierte Objektdiagramme aus Welcome1

inv Welcome3:
  forall Auction a:
    OD.Welcome3A implies OD.Welcome3B

Um die Verwendung anonymer Objekte genau zu verstehen, dient das Beispiel 4.21(a), das äquivalent zur Konjunktion aus dem Objektdiagramm 4.21(b) und der folgenden OCL-Formel InvA1214B ist (die die Variable ac1214) noch nicht bindet):

inv InvA1214B:
  exists Person anon1, anon2: OD.A1214B


Lädt...
Abbildung 4.21: Anonyme Objekte

Der einzige Unterschied besteht in den von A1214A zur Verfügung gestellten Namen. Die anonymen Objekte werden in InvA1214B explizit benannt (anon1 und anon2) und durch Existenzquantoren eingeführt.

4.3.5 OCL-Bedingungen im Objektdiagramm

Die vorangegangenen Beispiele haben gezeigt, wie Objektdiagramme in OCL-Bedingungen eingebettet werden. Das ist selbstverständlich auch umgekehrt möglich. Dabei wird der Kontext durch das Objektdiagramm definiert und die OCL-Bedingung kann die darin modellierten Objekte zur Definition der Aussage nutzen. Dabei wird der Bindungsbereich der Objektnamen nicht begrenzt. Die Namen sind weiterhin außerhalb des Objektdiagramms und der OCL-Bedingung nutzbar. Deshalb wird der Kontext der OCL-Bedingung mittels import festgelegt. Wie Abbildung 4.22 zeigt, sind derartige OCL-Bedingungen auch in der Darstellungsform Teil des Objektdiagramms beziehungsweise dem Objektdiagramm zugeordnet.

Lädt...

import Time start, Time finish inv TwoBids1:

  start.timeSec <= finish.timeSec

import Time start, Time finish,
  BidMessage bid1, BidMessage bid2
  inv TwoBids2:

  start.timeSec <= bid1.biddingTime.timeSec &&
  bid1.biddingTime.timeSec <= bid2.biddingTime.timeSec &&
  bid2.biddingTime.timeSec <= finish.timeSec

import Auction a inv TwoBids3:

  auctionIdent == 800 &&
  title in {"Test","Probe"}

Abbildung 4.22: Auktion mit zwei Geboten und OCL-Bedingungen

Die angegebenen OCL-Bedingungen sind ganz unterschiedlicher Natur. TwoBids1 ist eine für Auktionsobjekte allgemein gültige Invariante. Sie könnte auch in einem Klassendiagramm formuliert werden. TwoBids2 ist eine Invariante über die beiden Gebote, die in der Nachrichtenliste an den Stellen 2 und 3 eingereiht sind. Diese Invariante könnte verallgemeinert werden, da sie sinngemäß für weitere Gebote der Nachrichtenliste gilt. TwoBids3 ist keine Invariante, sondern eine Präzisierung des Aussehens einer konkreten Objektstruktur. Dies ist typisch für die Beschreibung von Objektstrukturen für Tests. Allerdings hätte der Wert für das Attribut auctionIdent auch direkt in die Objektstruktur eingetragen werden können.

Das Beispiel 4.22 zeigt also bereits einige Anwendungsmöglichkeiten für OCL- Bedingungen in Objektdiagrammen . Dennoch wird der Beschreibungskomfort für Objektdiagramme im folgenden Abschnitt weiter verbessert, indem abstrakte Werte und OCL-Ausdrücke in das Objektdiagramm eingeführt werden.

4.3.6 Abstrakte Objektdiagramme

Die Modellierung mit Objektdiagrammen hat sich bei Attributen bisher darauf beschränkt, entweder eine Konstante anzugeben oder den Attributwert offen zu lassen. Dies wird nun verallgemeinert, indem als Attributwerte freie OCL-Ausdrücke angegeben werden können. Eine solche Anwendung zeigt das Objektdiagramm NBids in Abbildung 4.23, das als Qualifikatoren abstrakte Werte beinhaltet.

Lädt...

import BidMessage bid1, BidMessage bid2, int n, int m
  inv nGebote2:
    0 <n && n <=m && m <a.message.size implies
    bid1.biddingTime.timeSec <= bid2.biddingTime.timeSec

Abbildung 4.23: Auktion mit Geboten und verallgemeinerten OCL-Bedingungen

Die im vorherigen Objektdiagramm TwoBids benutzten konkreten Qualifikatoren zur Selektion in der Nachrichtenliste wurden in NBids durch abstrakte Werte ersetzt. Diese abstrakten Werte können in eine OCL-Bedingung importiert und dort zur Spezifikation von Eigenschaften genutzt werden.

OCL-Ausdrücke können die Zusammenhänge zwischen einzelnen Attributen und Qualifikatoren genauer beschreiben. Um zum Beispiel eine Testauktion aufzusetzen, die 100 Personen hat, kann das einfache Objektdiagramm NPersons aus Abbildung 4.24 verwendet werden. Darin wird der abstrakte Wert x verwendet, um das Aussehen der einzelnen Personen festzulegen. Durch die OCL-Bedingung Test32 werden die 100 Personen in der Testauktion festgelegt.

Lädt...

import Auction test32 inv Test32:
  forall int x in {1..100}: OD.NPersons

Abbildung 4.24: Auktion mit parametrisiertem Personen-Objekt

Durch die Forderung, dass es für jedes x aus der Menge 1..100 eine Inkarnation des Objektdiagramms gibt und die Attribute der Personenobjekte unterschiedlich belegt sind, muss es in Auktion test32 mindestens diese 100 Personenobjekte geben.

Die Nutzung von OCL-Ausdrücken in Objektdiagrammen ist insbesondere auch geeignet, um abgeleitete Attribute zu beschreiben. Dadurch können oft OCL-Bedingungen zur Beschreibung von abgeleiteten Elementen durch eine Darstellung im Objektdiagramm ersetzt werden.


Bernhard Rumpe. Agile Modellierung mit UML. Springer 2012