====== Entwurfsmuster allgemein ======
**Entwurfsmuster** (englisch **design patterns**) sind bewährte Lösungsschablonen (hier: Klassen und deren Beziehungen) für wiederkehrende Entwurfsprobleme. Ihre Verwendung sorgt für leichter wartbaren Programmcode. Sie reduziert damit den Aufwand und auch die Kosten bei der Softwareentwicklung. \\ \\
**Nur zur Info:** \\
//Ausgangspunkt der Verwendung von Entwurfsmustern in der Softwaretechnik war die Veröffentlichung des Buches "Design Patterns" durch Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides im Jahr 1994. Sie tragen den Ehrennamen "Gang of four", entsprechend ist das Buch als "GoF-Book" bekannt. Auch das Entwurfsmuster "Kompositum" wird in diesem Buch beschrieben.//
===== Implementierung einer Liste mit dem Entwurfsmuster "Kompositum" =====
Der Nachfolger des letzten Elementes der Liste soll nicht mehr den Wert ''null'' erhalten, sondern auf ein Abschluss-Objekt zeigen. Das wird uns etwas später die Möglichkeit geben, auf elegante Art und Weise ohne den fehlerträchtigen Wert ''null'' auszukommen. Sehen wir uns eine beispielhafte Liste mit vier Elementen im Objektdiagramm an:
{{ :listen:kompositum:objektdiagramm_einfach_verkettete_liste_kompositum_.svg?700 |}}
Damit das Attribut ''nachfolger'' sowohl auf ein ''Knoten''-Objekt als auch auf ein ''Abschluss''-Objekt zeigen kann, muss sein Datentyp eine Oberklasse von ''Knoten'' und ''Abschluss'' sein. Wir nennen diese Klasse ''Listenelement'' und implementieren sie als **abstrakte Klasse**. Alle Methoden der Klasse ''Listenelement'' sind abstrakt, d.h. sie werden dort nur deklariert, aber nicht mit Anweisungen gefüllt. Das geschieht erst in den Klassen ''Knoten'' und ''Abschluss'' -- und zwar auf unterschiedliche Weise!
==== Klassendiagramm ====
{{ :listen:kompositum:klassendiagramm_kompositum.svg |}}
**Warum speichert die Liste keine Referenz "ende" aufs letzte Element?** \\
In den vorangegangenen Kapiteln hatte die Warteschlange ein Attribut ''ende'', das auf das letzte Element der Liste zeigt, sowie ein Attribut ''anfang'', das auf das erste Element der Liste zeigt. Die obige Implementierung einer Liste mit dem Entwurfsmuster Kompositum hat nur das Attribut ''anfang''. Das macht insofern Sinn, als eine Liste weniger spezialisiert aufs Einfügen des letzten Elements ist wie eine Warteschlange. Der eigentliche Grund für diese Designentscheidung ist aber eine ganz pragmatische Überlegung: \\
Der [[https://www.lehrplanplus.bayern.de/fachlehrplan/gymnasium/12/informatik/grundlegend|Lehrplan]] macht zu dieser Frage keine Aussage. Es gibt Stand Herbst 2024 aber [[https://www.km.bayern.de/download/4-24-10/5_Gymnasium_LPPLUS.pdf|nur ein einziges zugelassenes Lehrbuch für den Informatikkurs in Jgst. 12]], sodass nicht unwahrscheinlich ist, dass sich die Ersteller/-innen der Abiturprüfungsaufgaben einigermaßen an die Konventionen dieses Buches halten. Da darin die Wartelistenimplementierungen ohne Kompositum ein Attribut ''ende'' besitzen, die Listenimplementierung mit Kompositum aber nicht, orientiere ich mich in diesem Skript an dieser Quelle.
==== Implementierung ====
===== Aufgaben zur Listenimplementierung mit Kompositum =====
[[.listenaufgaben:start|Hier einige Aufgaben zur Listenimplementierung mit Kompositum!]]
===== Trennung von Struktur und Inhalt =====
Im obigen Beispiel muss die Inhaltsklasse nicht verändert werden, wenn die Funktionalitäten der Liste programmiert werden. Das Prinzip **"Trennung von Struktur und Inhalt"** ist damit erfüllt. // //
**Bemerkung:** Die Trennung von Struktur und Inhalt wäre nicht gegeben, wenn man der Inhaltsklasse selbst das Attribut "nachfolger" und die Methoden ''getNachfolger'' sowie ''hintenAnfügen'' hinzugefügt hätte.
====== Das Entwurfsmuster "Kompositum" ======
Die Kernidee des Entwurfsmusters "Kompositum" besteht darin, dass in einer zusammengesetzten Datenstruktur die "innen liegenden" Objekte (Fachbegriff: Kompositum, im obigen Beispiel: Knoten) und die "außen liegenden" Objekte (Fachbegriff: Blatt, im obigem Beispiel: Abschluss) Unterklassen einer abstrakten Klasse (Fachbegriff: Komponente, im obigen Beispiel: Listenelement) sind. In dieser abstrakten Klasse werden alle Methoden deklariert, die zum Verändern der Datenstruktur und zum Zugriff auf einzelne Elemente benötigt werden. Dadurch können die Kompositum-Objekte und die Blatt-Objekte im Hauptprogramm "gleich behandelt" werden.
Das **Entwurfsmuster Kompositum** (engl. composite) dient als Lösungsansatz für Situationen, in denen sowohl einfache als auch zusammengesetzte Elemente gleichbehandelt werden sollen und in denen eine Teil-Ganzes-Beziehung vorliegt. Es wird allgemein durch folgendes Klassendiagramm veranschaulicht:
{{ :listen:kompositum:pasted:20240927-104828.png?400 }}
**Bemerkung:** Die Bezeichnung "Blatt" in diesem Diagramm ist recht unglücklich, da sie nicht übereinstimmt mit dem Fachbegriff "Blatt" für außenliegende Knoten eines Baumes. Letzterer wird weit häufiger gebraucht. Im Englischen ist die Nomenklatur geringfügig besser: //Leaf// bezeichnet die Blatt-Klasse im Entwurfsmuster Kompositum, //leaf node// einen außenliegenden Knoten eines Baumes.
===== Beispiel: Dateisystem =====
Eine Möglichkeit zur anschaulichen Anwendung des Kompositums auf eine vertraute Struktur bietet das Dateisystem, das auf einem Laufwerk (Festplatte, USB-Stick, …) zu finden ist:
{{ :listen:kompositum:pasted:20240927-105003.png }}
Wie gewohnt kann ein Laufwerk hier Dateien und Ordner enthalten, ein Ordner wiederum (Unter-)Ordner und Dateien (die keine weiteren Objekte enthalten). Gemeinsame Methoden könnten z.B. der Ermittlung der Größe von Dateien und Ordnern dienen. Die Klasse Laufwerk steht außerhalb des Entwurfsmusters Kompositum.
===== Vorteile/Nachteile =====
Gegenüber einer Implementierung mit Knoten-Objekten aber ohne Abschluss-Objekt ergeben sich folgende Vorteile/Nachteile: \\ \\
**Vorteile:** \\
* Gleichbehandlung der unterschiedlichen Listenbestandteile möglich
* Keine Überprüfung auf null-Werte mehr
* Stärkere Strukturierung
**Nachteile:** \\
* Programmieraufwand ist höher
* Mehr beteiligte Klassen
* deutlich schlechtere Performance