2015-08-13 23:54:40 +02:00
---
layout: pattern
title: Composite
folder: composite
2015-08-15 18:03:05 +02:00
permalink: /patterns/composite/
2015-08-20 21:40:07 +02:00
categories: Structural
2021-05-19 10:49:05 -06:00
language: en
2015-09-22 18:25:56 +05:30
tags:
2019-12-13 22:22:11 +02:00
- Gang of Four
2015-08-13 23:54:40 +02:00
---
2016-01-03 21:14:30 +01:00
## Intent
2020-08-29 16:17:15 +03:00
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients
treat individual objects and compositions of objects uniformly.
2015-08-13 23:54:40 +02:00
2017-08-31 22:11:58 +03:00
## Explanation
2021-06-24 15:57:20 +03:00
Real-world example
2017-08-31 22:11:58 +03:00
2020-08-29 16:17:15 +03:00
> Every sentence is composed of words which are in turn composed of characters. Each of these
2021-06-24 15:57:20 +03:00
> objects are printable and they can have something printed before or after them like sentence
> always ends with full stop and word always has space before it.
2017-08-31 22:11:58 +03:00
In plain words
2021-06-24 15:57:20 +03:00
> Composite pattern lets clients uniformly treat the individual objects.
2017-08-31 22:11:58 +03:00
Wikipedia says
2020-08-29 16:17:15 +03:00
> In software engineering, the composite pattern is a partitioning design pattern. The composite
> pattern describes that a group of objects is to be treated in the same way as a single instance of
> an object. The intent of a composite is to "compose" objects into tree structures to represent
> part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects
> and compositions uniformly.
2017-08-31 22:11:58 +03:00
**Programmatic Example**
2020-08-29 16:17:15 +03:00
Taking our sentence example from above. Here we have the base class `LetterComposite` and the
different printable types `Letter` , `Word` and `Sentence` .
2017-08-31 22:11:58 +03:00
2018-03-28 01:35:43 -04:00
```java
2017-08-31 22:11:58 +03:00
public abstract class LetterComposite {
2019-11-12 22:12:47 +02:00
2020-07-30 20:28:47 +03:00
private final List< LetterComposite > children = new ArrayList< >();
2019-11-12 22:12:47 +02:00
2017-08-31 22:11:58 +03:00
public void add(LetterComposite letter) {
children.add(letter);
}
2019-11-12 22:12:47 +02:00
2017-08-31 22:11:58 +03:00
public int count() {
return children.size();
}
2019-11-12 22:12:47 +02:00
protected void printThisBefore() {
}
protected void printThisAfter() {
}
2017-08-31 22:11:58 +03:00
public void print() {
printThisBefore();
2019-11-12 22:12:47 +02:00
children.forEach(LetterComposite::print);
2017-08-31 22:11:58 +03:00
printThisAfter();
}
}
public class Letter extends LetterComposite {
2019-11-12 22:12:47 +02:00
2020-07-30 20:28:47 +03:00
private final char character;
2019-11-12 22:12:47 +02:00
2017-08-31 22:11:58 +03:00
public Letter(char c) {
2019-11-12 22:12:47 +02:00
this.character = c;
2017-08-31 22:11:58 +03:00
}
2019-11-12 22:12:47 +02:00
2017-08-31 22:11:58 +03:00
@Override
protected void printThisBefore() {
2019-11-12 22:12:47 +02:00
System.out.print(character);
2017-08-31 22:11:58 +03:00
}
}
public class Word extends LetterComposite {
2019-11-12 22:12:47 +02:00
2017-08-31 22:11:58 +03:00
public Word(List< Letter > letters) {
2019-11-12 22:12:47 +02:00
letters.forEach(this::add);
}
public Word(char... letters) {
for (char letter : letters) {
this.add(new Letter(letter));
2017-08-31 22:11:58 +03:00
}
}
2019-11-12 22:12:47 +02:00
2017-08-31 22:11:58 +03:00
@Override
protected void printThisBefore() {
System.out.print(" ");
}
}
public class Sentence extends LetterComposite {
2019-11-12 22:12:47 +02:00
2017-08-31 22:11:58 +03:00
public Sentence(List< Word > words) {
2019-11-12 22:12:47 +02:00
words.forEach(this::add);
2017-08-31 22:11:58 +03:00
}
2019-11-12 22:12:47 +02:00
2017-08-31 22:11:58 +03:00
@Override
protected void printThisAfter() {
System.out.print(".");
}
}
```
2020-08-29 16:17:15 +03:00
Then we have a messenger to carry messages:
2017-08-31 22:11:58 +03:00
2018-03-28 01:35:43 -04:00
```java
2017-08-31 22:11:58 +03:00
public class Messenger {
2019-11-12 22:12:47 +02:00
2017-08-31 22:11:58 +03:00
LetterComposite messageFromOrcs() {
2019-11-12 22:12:47 +02:00
var words = List.of(
new Word('W', 'h', 'e', 'r', 'e'),
new Word('t', 'h', 'e', 'r', 'e'),
new Word('i', 's'),
new Word('a'),
new Word('w', 'h', 'i', 'p'),
new Word('t', 'h', 'e', 'r', 'e'),
new Word('i', 's'),
new Word('a'),
new Word('w', 'a', 'y')
);
2017-08-31 22:11:58 +03:00
return new Sentence(words);
2019-11-12 22:12:47 +02:00
2017-08-31 22:11:58 +03:00
}
LetterComposite messageFromElves() {
2019-11-12 22:12:47 +02:00
var words = List.of(
new Word('M', 'u', 'c', 'h'),
new Word('w', 'i', 'n', 'd'),
new Word('p', 'o', 'u', 'r', 's'),
new Word('f', 'r', 'o', 'm'),
new Word('y', 'o', 'u', 'r'),
new Word('m', 'o', 'u', 't', 'h')
);
2017-08-31 22:11:58 +03:00
return new Sentence(words);
2019-11-12 22:12:47 +02:00
2017-08-31 22:11:58 +03:00
}
2019-11-12 22:12:47 +02:00
2017-08-31 22:11:58 +03:00
}
```
2020-08-29 16:17:15 +03:00
And then it can be used as:
2017-08-31 22:11:58 +03:00
2018-03-28 01:35:43 -04:00
```java
2021-06-24 15:57:20 +03:00
var messenger = new Messenger();
LOGGER.info("Message from the orcs: ");
messenger.messageFromOrcs().print();
LOGGER.info("Message from the elves: ");
messenger.messageFromElves().print();
```
The console output:
```
Message from the orcs:
Where there is a whip there is a way.
Message from the elves:
Much wind pours from your mouth.
2017-08-31 22:11:58 +03:00
```
2015-08-13 23:54:40 +02:00
2019-12-07 20:01:13 +02:00
## Class diagram
2020-08-29 16:17:15 +03:00
2019-12-07 20:01:13 +02:00

2016-01-03 21:14:30 +01:00
## Applicability
2020-08-29 16:17:15 +03:00
2016-01-03 21:14:30 +01:00
Use the Composite pattern when
2015-08-13 23:54:40 +02:00
2020-08-29 16:17:15 +03:00
* You want to represent part-whole hierarchies of objects.
* You want clients to be able to ignore the difference between compositions of objects and
individual objects. Clients will treat all objects in the composite structure uniformly.
2015-08-13 23:54:40 +02:00
2021-06-24 15:57:20 +03:00
## Known uses
2015-08-13 23:54:40 +02:00
* [java.awt.Container ](http://docs.oracle.com/javase/8/docs/api/java/awt/Container.html ) and [java.awt.Component ](http://docs.oracle.com/javase/8/docs/api/java/awt/Component.html )
2015-08-15 18:03:05 +02:00
* [Apache Wicket ](https://github.com/apache/wicket ) component tree, see [Component ](https://github.com/apache/wicket/blob/91e154702ab1ff3481ef6cbb04c6044814b7e130/wicket-core/src/main/java/org/apache/wicket/Component.java ) and [MarkupContainer ](https://github.com/apache/wicket/blob/b60ec64d0b50a611a9549809c9ab216f0ffa3ae3/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java )
2015-09-22 18:25:56 +05:30
2016-01-03 21:14:30 +01:00
## Credits
2015-09-22 18:25:56 +05:30
2020-07-06 13:31:07 +03:00
* [Design Patterns: Elements of Reusable Object-Oriented Software ](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59 )
2020-07-07 18:05:11 +03:00
* [Head First Design Patterns: A Brain-Friendly Guide ](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b )
2020-07-07 18:44:00 +03:00
* [Refactoring to Patterns ](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7 )