# Composite Pattern: Musterlösung für Teil-Ganzes-Hierarchien

Dynamische Datenstrukturen wie die Baumstruktur einer Dateiverwaltung oder eines Programm-Interfaces erfordern ein klares, möglichst **eindeutiges Hierarchie-Gefüge**. Die Umsetzung solcher Strukturen ist häufig jedoch gar nicht so einfach. So gilt es beispielsweise darauf zu achten, dass nicht jedes Mal der Typ eines Objekts vor der eigentlichen Datenverarbeitung abgefragt werden muss, da ein solches Szenario weder effizient noch performant wäre. Insbesondere, wenn viele primitive Objekte auf zusammengesetzte Objekte treffen, empfiehlt sich daher der Einsatz des sogenannten Composite Design Patterns (dt. *Kompositum-Entwurfsmuster*). Der Softwaredesign-Ansatz ermöglicht es Clients, individuelle und zusammengesetzte Objekte einheitlich zu behandeln, indem ihre Unterschiede vor dem Client verborgen werden.

## Was ist das Composite Pattern (Composite-Muster)?

Das Composite Design Pattern (dt. Kompositum-Entwurfsmuster), kurz Composite Pattern, ist eines der 23 GoF-[Design-Pattern](https://www.ionos.de/digitalguide/websites/web-entwicklung/was-sind-design-patterns/ "Was sind Design Patterns?") für die **Software-Entwicklung**, die 1994 von Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides (gemeinsam auch als „**G**ang **o**f **F**our“ bekannt) veröffentlicht wurden. Wie beispielsweise auch das [Facade Pattern](https://www.ionos.de/digitalguide/websites/web-entwicklung/was-ist-das-facade-pattern/ "Was ist das Facade Pattern?") und das [Decorator Pattern](https://www.ionos.de/digitalguide/websites/web-entwicklung/was-ist-das-decorator-pattern/ "Was ist das Decorator Pattern?") zählt es dabei zu den Strukturmustern, deren grundlegende Funktion es ist, **Objekte und Klassen zu größeren Strukturen zusammenzufassen**.

## Welche Probleme löst das Composite-Entwurfsmuster?

Der grundsätzliche Zweck des Composite Design Patterns ist – wie bei allen GoF-Mustern – der **bestmögliche Umgang mit wiederkehrenden Design-Problemen** in der **objektorientierten Entwicklung**. Das gewünschte Ergebnis ist eine möglichst flexible Software, die sich durch leicht implementierbare, testbare, austauschbare und wiederverwendbare Objekte auszeichnet. Das Composite Pattern beschreibt zu diesem Zweck einen Weg, wie sich einzelne Objekte und zusammengesetzte Objekte auf die gleiche Weise behandeln lassen. Auf diese Weise lässt sich eine Objektstruktur schaffen, die **leicht verständlich** ist und **maximal effiziente Client-Zugriffe** ermöglicht. Zudem wird auch die Fehleranfälligkeit des Codes minimiert.

## Composite Design Pattern: Grafische Darstellung (UML)

Um die angesprochenen, effizienten Teil-Ganzes-Hierarchien umzusetzen, sieht das Composite-Muster die Implementierung eines **einheitlichen Komponenten-Interfaces** für simple Teil-Objekte, die auch als **Leaf-Objekte** (engl. für „Blatt“) bezeichnet werden, und zusammengesetzte **Composite-Objekte** (engl. für „zusammengesetzt“) vor. Einzelne Leaf-Objekte binden dieses Interface direkt ein, Composite-Objekte geben konkrete **Client-Anforderungen an die Schnittstelle** automatisch an ihre untergeordneten Komponenten weiter. Für den Client spielt es dabei keine Rolle, um welchen Typ von Objekt (Teil oder Ganzes) es sich handelt, da er lediglich das Interface ansprechen muss.

Das nachfolgende Klassendiagramm in der Modellierungssprache [UML](https://www.ionos.de/digitalguide/websites/web-entwicklung/uml-modellierungssprache-fuer-objektorientierte-programmierung/ "UML: Modellierungssprache für objektorientierte Programmierung") macht die **Zusammenhänge** und **Hierarchien** in einer Software auf Composite-Pattern-Basis deutlicher.

[![Bild: UML-Diagramm zum Composite Pattern](https://www.ionos.de/digitalguide/fileadmin/_processed_/0/e/csm_composite-pattern-uml-diagramm_3bd220cdfd.webp "UML-Diagramm zum Composite Pattern")](https://www.ionos.de/digitalguide/fileadmin/DigitalGuide/Schaubilder/composite-pattern-uml-diagramm.png) UML-Diagramm zum Composite Pattern ## Stärken und Schwächen des Composite-Entwurfsmusters

Das Composite Pattern zählt in der Softwareentwicklung zu einer festen Größe. Insbesondere **Projekte mit stark verschachtelten Strukturen** profitieren von dem praktischen Ansatz für die Organisation von Objekten: Ob primitives Objekt oder zusammengesetztes Objekt, ob mit simplen oder mit komplexen Abhängigkeiten – die **Tiefe und Breite der Verschachtelung** spielt beim Composite Design Pattern grundsätzlich **keine Rolle**. Die Unterschiede zwischen den Objektarten können vom Client gänzlich ignoriert werden, sodass keine separaten Funktionen für den Zugriff erforderlich sind. Das bringt den Vorteil mit sich, dass der Client-Code einfach und schlank bleibt.

Eine weitere Stärke des Kompositum-Entwurfsmusters ist die **Flexibilität** und einfache **Erweiterbarkeit**, die das Pattern einer Software verleiht: Das universelle Komponenten-Interface ermöglicht es, neue Leaf- und Composite-Objekte ohne Code-Änderungen einzubinden – ob auf Client-Seiten oder bei bereits bestehenden Objektstrukturen.

Auch wenn das Composite Pattern und seine einheitliche Schnittstelle eine Reihe von Vorteilen bieten, ist diese Musterlösung nicht frei von Schwächen. Insbesondere das **Interface** kann Entwicklern eine Menge Kopfzerbrechen bereiten. Bereits die **Implementierung** stellt die Verantwortlichen vor große Herausforderungen, da beispielsweise zu entscheiden ist, welche Operationen konkret in der Schnittstelle und welche in den Composite-Klassen definiert werden sollen. Auch eine **nachträgliche Anpassung der Composite-Eigenschaften** (zum Beispiel die Einschränkung, welche Child-Elemente erlaubt sind) erweist sich meist als **kompliziert** und nur schwer zu realisieren.

<table>
  <thead>
    <tr>
      <th>Vorteile</th>
      <th>Nachteile</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Liefert alles, um stark verschachtelte Objektstrukturen darzustellen</td>
      <td>Implementierung des Komponenten-Interfaces ist sehr herausfordernd</td>
    </tr>
    <tr>
      <td>Schlanker, leicht verständlicher Programmcode</td>
      <td>Nachträgliche Anpassung der Composite-Eigenschaften sind kompliziert und zur schwer umzusetzen.</td>
    </tr>
    <tr>
      <td>Gute Erweiterbarkeit</td>
      <td></td>
    </tr>
  </tbody>
</table>

## Anwendungsszenarien für das Composite Pattern

Der Einsatz des Composite-Musters zahlt sich überall dort aus, wo Operationen auf dynamische Datenstrukturen ausgeführt werden sollen, deren **Hierarchie** von komplexer Breite und/oder Tiefe ist. Man spricht in diesem Fall auch von einer **binären Baumstruktur**, die für die verschiedensten Softwareszenarios interessant ist und häufig zur Verwendung kommt. Typische Beispiele sind:

**Dateisysteme**: Zu den wichtigsten Komponenten von Geräte-Software gehören [Dateisysteme](https://www.ionos.de/digitalguide/server/knowhow/dateisysteme/). Diese lassen sich optimal mit dem Composite Pattern abbilden: Einzelne **Dateien** als Leaf-Objekte und **Ordner** – die ihrerseits selbst Dateien oder weitere Ordner enthalten können – als Composite-Objekte.

**Software-Menüs**: Auch Programmmenüs stellen einen typischen Use Case für eine binäre Baumstruktur nach dem Composite Design Pattern dar. In der **Menüleiste** befinden sich ein oder mehrere Wurzeleinträge (Composite-Objekte) wie „Datei“. Diese gewähren Zugriff auf verschiedene Menüpunkte, die wahlweise direkt **klickbar sind** (Leaf) oder weitere **untergliederte Menüs** (Composite) enthalten.

**Grafische Benutzeroberflächen (GUIs)**: Auch bei der Gestaltung von [grafischen Benutzeroberflächen](https://www.ionos.de/digitalguide/websites/webdesign/grafische-benutzeroberflaeche-alles-fuer-ein-gutes-ui/) können Baumstrukturen und das Composite-Entwurfsmuster eine wichtige Rolle spielen. Abseits von simplen Leaf-Elementen wie Buttons, Textfeldern oder Checkboxen sorgen zusammenfassende Composite-Behälter wie Frames oder Panels für eine klare Struktur und mehr Übersichtlichkeit.

## Code-Beispiel: Composite Pattern

In kaum einer Programmiersprache ist der Composite-Pattern-Ansatz so fest etabliert wie in Java. Unter anderem bildet das Muster beispielsweise auch die Basis des **Abstract Window Toolkits** (AWT), eines praktischen und beliebten API mit rund 50 einsatzfertigen Java-Klassen für die Entwicklung plattformübergreifender Java-Oberflächen. Auch im nachfolgenden Code-Beispiel, das sich am Beitrag [„Composite Design Pattern in Java“ auf baeldung.com](https://www.baeldung.com/java-composite-pattern "baeldung.com: Composite Design Pattern in Java") orientiert, haben wir uns daher für die populäre Programmiersprache entschieden.

Im Praxis-Beispiel soll die **hierarchische Struktur von Abteilungen** (departments) in einem **Unternehmen** (company) dargestellt werden. Zunächst wird hierfür das **Komponenten-Interface** „*Department*“ definiert:

```none
public interface Department {
	void printDepartmentName();
}
```

Anschließend werden die **zwei einfachen Leaf-Klassen** „*FinancialDepartment*“ (für die Finanzabteilung) und „*SalesDepartment*“ (für die Verkaufsabteilung) definiert. Beide **implementieren die Methode** printDepartmentName() von der Komponenten-Schnittstelle, enthalten aber ansonsten keine weiteren Department-Objekte.

```none
public class FinancialDepartment implements Department {
	private Integer id;
	private String name;
	public void printDepartmentName() {
		System.out.println(getClass().getSimpleName());
	}
	// standard constructor, getters, setters
}
```

```none
public class SalesDepartment implements Department {
	private Integer id;
	private String name;
	public void printDepartmentName() {
		System.out.println(getClass().getSimpleName());
	}
	// standard constructor, getters, setters
}
```

Eine zur Hierarchie passende **Composite-Klasse** wird schließlich mit „HeadDepartment“ definiert. Diese setzt sich **aus mehreren Department-Komponenten** zusammen und enthält zusätzlich zu der printDepartmentName()-Methode auch Methoden, um weitere Elemente hinzuzufügen (*addDepartment*) oder vorhandene Elemente zu entfernen (*removeDepartment*):

```none
public class HeadDepartment implements Department {
	private Integer id;
	private String name;
	private List<department> childDepartments;</department>
	public HeadDepartment(Integer id, String name) {
		this.id = id;
		this.name = name;
		this.childDepartments = new ArrayList<>();
	}
	public void printDepartmentName() {
		childDepartments.forEach(Department::printDepartmentName);
	}
	public void addDepartment(Department department) {
		childDepartments.add(department);
	}
	public void removeDepartment(Department department) {
		childDepartments.remove(department);
	}
}
```


This is a markdown version of: [https://www.ionos.de/digitalguide/websites/web-entwicklung/was-ist-das-composite-pattern/](https://www.ionos.de/digitalguide/websites/web-entwicklung/was-ist-das-composite-pattern/) for AI/LLM consumption.