Achtung:

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

Aus Projektwiki - ein Wiki mit Schülern für Schüler.
Wechseln zu: Navigation, Suche

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: ObjektdiagrammVorher:Objektdiagramm, bevor die Methode EinfuegenVor ausgeführt wurde.


Wird die Methode EinfuegenVor(d_neu, d_vergleich) nun ausgeführt, wird nach d_neu und d_vergleich verlangt. EinfuegenVor Methodenaufruf

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: ObjektdiagrammVorher:Objektdiagramm, nach dem Aufruf der Methode EinfuegenVor.


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;
       }
   }