Dieses Wiki, das alte(!) Projektwiki (projektwiki.zum.de)
wird demnächst gelöscht.
Bitte sichere Deine Inhalte zeitnah,
wenn Du sie weiter verwenden möchtest.
Gerne kannst Du natürlich weiterarbeiten
im neuen Projektwiki (projekte.zum.de).Liste in perfekter Komposition
Inhaltsverzeichnis |
Entwurfsmuster Kompositum
Problematik
Die Zielsetzung ist die Trennung von Struktur und Inhalt. Dies wurde durch die Klasse KNOTEN bereits zum Teil erfüllt. Jedoch verhält sich der letzte Knoten in der Liste anders als die Restlichen, wegen der Überprüfung, ob es einen Nachfolger gibt.
if(nachfolger != null)
{}
Lösung
Optimaler wäre es, wenn alle Objekte der Klasse KNOTEN sich gleich verhalten und die Abfrage nach dem Nachfolger nicht mehr nötig ist.
Abhilfe schafft eine neue Klasse ABSCHLUSS, welche stets das letzte Objekt in der Liste darstellt und die Aufgaben des eigentlichen letzten Knotens übernimmt.
Dazu wird eine abstrakte Basisklasse LISTENELEMENT erstellt, von welcher die Klasse KNOTEN und ABSCHLUSS erben.
In der Klasse ABSCHLUSS wird jediglich das ausformuliert, was der letzte Knoten machen müsste.
Objekte der Klasse ABSCHLUSS
Sekundäre Überschrift
Objektsituation vor und nach dem Aufruf der Methode EinfuegenVor
Vorher
Damit die Methode EinfuegenVor ausgeführt werden kann, muss bereits ein Objekt der Klasse LISTE erzeugt sein.
Dies würde zunächst ausreichen, doch um die Methode korrekt ausführen zu können, sollte noch ein Objekt der Klasse DATENELEMENT (z.B PATIENT) erzeugt werden und ein weiteres sollte bereits in der Liste eingefügt worden sein.
Das Objektdiagramm sieht dementsprechend so aus:
Wird die Methode EinfuegenVor(d_neu, d_vergleich) nun ausgeführt, wird nach d_neu und d_vergleich verlangt.
d_neu ist das Datenelement, welches eingefügt werden soll.
d_vergleich ist das Datenelement, welches verglichen wird und dann der Nachfolger von d_neu wird.
d_neu kann entweder ein neu erzeugtes Datenelement oder ein bereits vorhandenes, aber noch nicht eingefügtes Datenelement, sein.
d_vergleich kann nur ein Datenelement sein, dass bereits in der Liste eingefügt ist.
Nachher
Ist die Methode fertig ausgeführt befindet sich das neue Datenelement vor dem verglichenen Datenelement.
- Alle Attributwerte (z.B. Nachfolger) von d_vergleich bleiben gleich
- d_vergleich ist nun der Nachfolger von d_neu
- Der frühere Vorgängerknoten von d_vergleich hat nun d_neu als Nachfolger
Objektdiagramm nach dem dem Aufruf:
Sonderfälle
Damit die Methode wirkungsvoll ausgeführt werden kann, reicht ein Objekt der Klasse LISTE nicht mehr aus. Zwar kann die Methode ausgeführt werden, doch würde die Fehlermeldung einer NullPointerException kommen. Dies passiert deswegen, weil die Methode ein neues Datenelement benötigt, welches eingefügt werden soll (d_neu) und eines, dass als vergleicht dient (d_vergleich).
Deswegen sollten Objekte dieser Klassen ebenfalls erzeugt sein:
- KNOTEN (1 pro Datenelement)
- DATENELEMENT (z.B PATIENT)
- ABSCHLUSS
Vereinfachung des Quelltexte
Quelltext der Methode LaengeGeben
In Klasse LISTE
int LaengeGeben() { return anfang.RestlaengeGeben(); }
In Klasse KNOTEN
int RestlaengeGeben() { return nachfolger.RestlaengeGeben()+1; }
In Klasse ABSCHLUSS
int RestlaengeGeben() { return 0; }
Quelltext der Methode EinfuegenVor
In Klasse KNOTEN
KNOTEN EinfuegenVor(DATENELEMENT dneu, DATENELEMENT d_vergleich) { if(daten != d_vergleich) { nachfolger = nachfolger.EinfuegenVor(dneu, d_vergleich); return this; } else { KNOTEN kneu; kneu = new KNOTEN(dneu, this); return kneu; } }