Partitionierung von Modellen mit Faktor-IPS
Umgang mit Beziehungen: Derived Union
Betrachten wir noch einmal das UML-Modell mit den Vererbungsbeziehungen zwischen Grundmodell und Hausratmodell (obige Abbildung). Es gibt eine Kompositbeziehung zwischen den spartenübergreifenden Klassen Vertrag und Deckung einerseits und zwischen dem Hausratvertrag und der Hausratzusatzdeckung bzw. -grunddeckung andererseits. Unsere Erwartungshaltung ist dabei die folgende:
-
Zum
HausratVertragkönnen eineHausratGrunddeckungund beliebig vieleHausratZusatzdeckung-Objekte hinzugefügt werden, aber zum Beispiel keine KFZ-Deckungen. -
Wenn man eine
HausratGrunddeckungoderHausratZusatzdeckungzumHausratVertraghinzufügt, erhält man diese auch zurück, wenn man sich vomVertragalle Deckungen (also die, deren TypenDeckungoder Subklassen vonDeckungsind) zurückgeben lässt.
Diese erwartete Semantik ist aber nicht im Modell enthalten. Die Beziehungen zwischen Vertrag und Deckung bzw. Hausratvertrag und Hausratgrunddeckung/-Zusatzdeckung sind zunächst
voneinander unabhängige Beziehungen. Ein Beispiel verdeutlicht dies:
In dem folgenden Codeausschnitt erzeugen wir eine Instanz von HausratVertrag und eine Instanz von HausratZusatzdeckung und fügen mit der Methode addHausratZusatzdeckung(…) die Zusatzdeckung dem Hausratvertrag hinzu. Fragen wir nun den Vertrag mit getDeckungen() nach seinen Deckungen, erhalten wir eine leere Liste zurück. Fragen wir den HausratVertrag mit getHausratZusatzdeckungen() nach seinen Zusatzdeckungen, bekommen wir dagegen erwartungsgemäß eine Liste mit der Zusatzdeckung zurück.
HausratVertrag hausratVertrag = new HausratVertrag();
HausratZusatzdeckung neueZusatzdeckung = new HausratZusatzdeckung();
hausratVertrag.addHausratZusatzdeckung(neueZusatzdeckung);
hausratVertrag.getDeckungen(); // liefert eine leere Liste
hausratVertrag.getHausratZusatzdeckungen(); // liefert eine ArrayList mit neueZusatzdeckung als Element
Wenn wir uns den Code anschauen, der aus dem Modell generiert wird, verstehen wir, warum. Die Komposit-Beziehungen zu Deckung, HausratGrunddeckung und HausratZusatzdeckung werden in Java jeweils als eigene Membervariablen abgebildet:
public abstract class Vertrag /* ... */ {
private List<IDeckung> deckungen = new ArrayList<>();
public List<IDeckung> getDeckungen() {
return Collections.unmodifiableList(deckungen);
}
// ...
}
public class HausratVertrag extends Vertrag /* ... */ {
private HausratGrunddeckung hausratGrunddeckung = null;
private List<HausratZusatzdeckung> hausratZusatzdeckungen = new ArrayList<>();
public HausratGrunddeckung getHausratGrunddeckung() {
return hausratGrunddeckung;
}
public List<? extends HausratZusatzdeckung> getHausratZusatzdeckungen() {
return Collections.unmodifiableList(hausratZusatzdeckungen);
}
// ...
}
Die von uns gewünschte Semantik können wir erreichen, indem wir die Deckungen nicht in einer Membervariablen des Vertrags verwalten, sondern die Deckungen eines Vertrags aus den anderen beiden Beziehungen ermitteln. Der folgende Codeausschnitt zeigt, wie dies gehen kann:
public List<IDeckung> getDeckungen() {
List<IDeckung> result = new ArrayList<>();
// wenn es eine Grunddeckung gibt, fuege diese zu den Deckungen hinzu
HausratGrunddeckung grunddeckung = getHausratGrunddeckung();
if (grunddeckung != null) {
result.add(grunddeckung);
}
// nun fuege alle Zusatzdeckungen hinzu
result.addAll(getHausratZusatzdeckungen());
return result;
}
Damit wird die Beziehung Vertrag–Deckung zu einer abgeleiteten Beziehung. Sie entspricht der Obermenge der beiden anderen Beziehungen. Solche Typen von Beziehungen werden in UML auch als „derived union" bezeichnet. Das folgende Klassendiagramm zeigt das Modell unter Verwendung der abgeleiteten Vereinigung in UML Notation:
Um die Beziehung Vertrag–Deckung als abgeleitete Vereinigung zu markieren, öffnen Sie den Editor für die Klasse Vertrag und dann den Dialog zur Bearbeitung der Beziehung. In dem Dialog haken Sie die Checkbox gemäß der folgenden Abbildung an.
Daraufhin markieren Sie die Beziehungen im Hausratmodell als Teilmenge dieser abgeleiteten Vereinigung.