Grundlagen der Programmierung: Entwurfsmuster

Kompositum: Umsetzung

Testen Sie unsere 1983 Kurse

10 Tage kostenlos!

Jetzt testen Alle Abonnements anzeigen
In diesem Video erfahren Sie, wie Sie das Entwurfsmuster "Kompositum" praktisch umsetzen und welche Auswirkungen der Einsatz dieses Musters haben kann.
07:20

Transkript

Durch die Anwendung des Entwurfsmusters Kompositum lassen sich für einen Client die Elemente eines Baumes, also die Knoten und die Blätter, auf die gleiche Weise behandeln. Werfen wir nun einen Blick auf die praktische Umsetzung. Dazu schauen wir uns zuerst die Basisklasse an Aufgabe. Das ist eine abstrakte Klasse, denn sie ist nicht dazu gedacht, dass tatsächlich Instanzen davon erzeugt werden sollen. Hier haben wir das Attribut für die Beschreibung und den entsprechenden Konstruktor, der das Attribut setzt. Außerdem gibt es noch einen Getter, mit dem wir die Beschreibung lesen können. Nun kommt der wesentliche Punkt dieses Musters. Nämlich hier diese beiden Methoden, das ist die gemeinsame Funktionalität, die sowohl die Knoten als auch die Blätter anbieten müssen. Beide müssen also Methoden anbieten, mit denen man sie als erledigt markieren kann und rausfinden kann, ob sie bereits erledigt wurden. Die erste der beiden Unterklassen ist die EinzelAufgabe. Das werden also die Blätter unseres Baumes. Hier ist das Attribut, indem sich die Aufgabe merkt, ob sie bereits erledigt wurde. Der Konstruktor ruft einfach nur den Konstruktor der Oberklasse auf und gibt die Beschreibung durch. Jetzt folgt die Implementierung der beiden abstrakten Methoden. Mit der Methode wirdErledigt wird das Attribut auf true gesetzt und es wird eine kurze Meldung ausgegeben, dass diese Teilaufgabe soeben ausgeführt wurde. Die Methode istErledigt gibt einfach das Attribut zurück. Damit kommen wir nun zur AufgabenListe. Die AufgabenListe ist natürlich ebenfalls Unterklasse von Aufgabe. Das ist die Idee dieses Musters. Da die AufgabenListe der Knoten in unserem Baum ist, halten wir hier in Aufgaben die direkten Unterelemente dieses Knotens fest. Im Konstruktor reichen wir wieder die Beschreibung nach oben durch und initialisieren die Aufgaben. Die Implementierung der Methode wirdErledigt sieht natürlich anders aus als bei der EinzelAufgabe. Wenn die gesamte AufgabenListe als abgeschlossen, erledigt, fertig markiert werden soll, dann erreicht sie dass, indem sie zu all ihren direkten Kindelementen geht und jedes dieser Elemente ebenfalls als erledigt markiert. Wohl gemerkt, der Typ hier heißt Aufgabe, also das ist der Typ der Basisklasse und wenn dahinter jetzt zur Laufzeit eine EinzelAufgabe sitzt, dann wird deren Attribut entsprechend gesetzt. Wenn dahinter eine andere AufgabenListe sitzt, dann geht das Ganze in die nächste Ebene durch. Wenn ich die Liste fragen möchte, ob sie schon erledigt ist, muss sie natürlich auch dafür ihre Unterelemente konsultieren. Wenn wir in der Reihe dieser Elemente auch nur eins finden, das noch nicht erledigt wurde, dann können wir sofort false zurückgeben, andernfalls wenn wir erfolgreich durch die ganze Liste durchgegangen sind, geben wir true zurück. Mit anderen Worten, nur wenn alle Aufgaben, die in der Liste drinnen stehen erfolgreich abgeschlossen wurden, gilt auch die Liste selbst als erfolgreich abgeschlossen. Der Vollständigkeit halber noch ein kurze Blick auf die Methode hinzufuegen. Damit können wir natürlich unserer AufgabenListe einzelne Aufgaben hinzufügen. Beachten Sie auch hier wieder, dass es sich um den Basistyp handelt. Wir können also sowohl EinzelAufgaben als auch weitere AufgabenListen hinzufügen. Um das Ganze auch ausprobieren zu können, habe ich hier einen kleinen Testbaum zusammengesetzt. Ich beginne mit einer AufgabenListe und nenne sie abwaschen. In diese Liste füge ich dann drei EinzelAufgaben ein, nämlich Glaeser spuelen, Besteck putzen, Toepfe kratzen. Jetzt habe ich hier eine zweite AufgabenListe, die heißt dingeTun und das ist dann Was man halt so tun muss. Diese Liste dingeTun füge ich nun als erstes Element meiner Abwaschenliste hinzu. Nun baue ich mir noch zwei EinzelAufgaben, nämlich Muell runterbringen und Welt retten und füge sie ebenfalls in meine dingeTun AufgabenListe ein. Meine Hauptliste enthält nun also drei Elemente, nämlich diese beiden EinzelAufgaben und die diese abwaschen AufgabenListe. Die wiederum enthält dann drei Unterelemente, nämlich Glaeser spuelen, Besteck putzen, Toepfe kratzen. Um das Ganze bequem ausprobieren zu können, habe ich hier noch eine Methode anzeigen hinzugefügt. Die sieht so aus. Zuerst wird ein kurzer Text ausgegeben, dann die Beschreibung der entsprechenden Aufgabe und je nachdem, ob die Aufgabe erledigt ist oder noch nicht, wird ausgegeben erledigt oder noch nicht. Jetzt fragen wir erst mal ab. Erst mal nehmen wir den gesamten Baum, so wie er ist und schauen, wie der aktuelle Status ist. Ich führe das also aus und dann sehen wir, auf die Frage alles fertig bekommen wir Was man halt so tun muss ist noch nicht erledigt. Das war zu erwarten. Nun gehe ich zum Teilbaum abwaschen und hake diese AufgabenListe als erledigt ab. Dann frage ich die Hauptliste, ob jetzt alles fertig ist und ich frage den Abwaschbaum, ob er wenigstens schon abgeschlossen ist. Das Ergebnis sieht dann so aus. Zu Beginn natürlich wieder die Antwort auf unsere erste Frage. Hier wurde irgendwie zumindest noch nicht alles erledigt. Jetzt wird der Teilbaum Abwaschen als erledigt markiert. Das heißt also hier, die Teilaufgaben Glaeser spuelen, Besteck putzen, Toepfe kratzen wurden soeben ausgeführt. Wenn ich jetzt frage, ist jetzt alles fertig, dann erfahre ich, dass Was man halt so tun muss immer noch nicht erledigt ist, aber abgewaschen ist immerhin schon erledigt. Nun kümmern wir uns noch um die letzten Teilaufgaben. Das heißt, Muell runterbringen wird erledigt. Welt retten wird erledigt. Jetzt schauen wir noch einmal nach, wurde die Welt wirklich gerettet, indem wir dieses einzelne Element befragen und dann gehen wir nochmal zum Wurzelelement, das eine AufgabenListe ist und fragen auch dort nochmal nach. Bei der Ausführung sehen wir dann, bis hier hin ist wieder alles gleich. Wenn ich jetzt die Teilaufgaben Muell runterbringen und Welt retten als erledigt markiere, bekomme ich die entsprechenden Reaktionen. Teste jetzt, ob die Welt gerettet wurde. Dann erfahre ich, dass das erledigt ist und jetzt schauen wir noch einmal, ist jetzt also alles fertig, dann sehe ich Was man halt so tun muss ist erledigt. Unser Ziel bestand darin, dass wir sowohl mit den Knoten als auch mit den Blättern auf die gleiche Weise verfahren können. Genau das machen wir hier. Diese Methode anzeigen nimmt einfach eine Aufgabe. Ihr ist es dabei völlig egal, ob das eine EinzelAufgabe oder eine AufgabenListe ist. Von der Aufgabe kann die Beschreibung geholt werden und es kann getestet werden, ob sie erledigt wurde. Damit haben wir also unser Ziel erreicht. Fassen wir nochmal die wichtigsten Punkte zusammen. Durch die Verwendung dieses Entwurfsmusters können Blätter und Knoten eines Baumes auf die gleiche Weise verwendet werden. Der Zugriff für den Client wird dadurch einfacher, weil er sich nicht mehr darum kümmern muss, ob es sich im Einzelfall um ein Blatt oder um einen Knoten handelt. Zu den Nachteilen, die Basisklasse enthält nur die Methoden, die tatsächlich sowohl für die Blätter also auch für die Knoten vorgeschrieben werden sollen, die also vom Client für beide Arten aufgerufen werden können sollen. Wenn also eine der beiden Sorten, also entweder die Blätter oder die Knoten, zusätzliche Methoden enthalten, dann kann der Client auf diese nur mit zusätzlichem Aufwand zugreifen. Anders ausgedrückt, er muss dann wissen, um was es sich genau handelt. Wenn wir in unserem Beispiel einem Teilbaum ein weiteres Element hinzufügen wollen, dann genügt der Basistpy Aufgabe dafür nicht mehr. Wir müssen dann wissen, dass es eine AufgabenListe ist. Nun könnten wir natürlich die Methode hinzufuegen in die Basisklasse hochziehen. Auf diese Weise hätte der Client dann in jedem Fall Zugriff auf diese Methode. Dann hätten wir aber das umgekehrte Problem. Die Unterklasse EinzelAufgabe kann diese Funktionalität dann eigentlich nämlich nicht anbieten und müsste dann zum Beispiel eine Unsupported Operation Exception werfen, was für den Client dann auch wieder nicht so schön ist. Damit kennen Sie nun das Entwurfsmuster Kompositum und Sie sehen, Sie müssen einfach im Einzelfall entscheiden, ob für Sie die Vorteile überwiegen oder die Nachteile.

Grundlagen der Programmierung: Entwurfsmuster

Erhalten Sie einen fundierten Einstieg in das Thema Entwurfsmuster (Design Patterns) und erfahren Sie, wie Sie Entwurfsmuster in objektorientierten Programmiersprechen umsetzen.

2 Std. 49 min (33 Videos)
Derzeit sind keine Feedbacks vorhanden...
 

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!