Skip to content

Commit e00e67c

Browse files
committed
docs: update Composite docs
1 parent 48a5ede commit e00e67c

File tree

1 file changed

+121
-86
lines changed

1 file changed

+121
-86
lines changed

composite/README.md

Lines changed: 121 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,27 @@ title: Composite
33
category: Structural
44
language: en
55
tag:
6-
- Gang of Four
6+
- Gang of Four
7+
- Object composition
8+
- Recursion
79
---
810

11+
## Also known as
12+
13+
* Object Tree
14+
* Composite Structure
15+
916
## Intent
1017

11-
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients
18+
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients
1219
treat individual objects and compositions of objects uniformly.
1320

1421
## Explanation
1522

1623
Real-world example
1724

18-
> Every sentence is composed of words which are in turn composed of characters. Each of these
19-
> objects are printable and they can have something printed before or after them like sentence
25+
> Every sentence is composed of words which are in turn composed of characters. Each of these
26+
> objects are printable and they can have something printed before or after them like sentence
2027
> always ends with full stop and word always has space before it.
2128
2229
In plain words
@@ -25,85 +32,85 @@ In plain words
2532
2633
Wikipedia says
2734

28-
> In software engineering, the composite pattern is a partitioning design pattern. The composite
29-
> pattern describes that a group of objects is to be treated in the same way as a single instance of
30-
> an object. The intent of a composite is to "compose" objects into tree structures to represent
31-
> part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects
35+
> In software engineering, the composite pattern is a partitioning design pattern. The composite
36+
> pattern describes that a group of objects is to be treated in the same way as a single instance of
37+
> an object. The intent of a composite is to "compose" objects into tree structures to represent
38+
> part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects
3239
> and compositions uniformly.
3340
3441
**Programmatic Example**
3542

36-
Taking our sentence example from above. Here we have the base class `LetterComposite` and the
37-
different printable types `Letter`, `Word` and `Sentence`.
43+
Taking our sentence example from above. Here we have the base class `LetterComposite` and the
44+
different printable types `Letter`, `Word` and `Sentence`.
3845

3946
```java
4047
public abstract class LetterComposite {
4148

42-
private final List<LetterComposite> children = new ArrayList<>();
49+
private final List<LetterComposite> children = new ArrayList<>();
4350

44-
public void add(LetterComposite letter) {
45-
children.add(letter);
46-
}
51+
public void add(LetterComposite letter) {
52+
children.add(letter);
53+
}
4754

48-
public int count() {
49-
return children.size();
50-
}
55+
public int count() {
56+
return children.size();
57+
}
5158

52-
protected void printThisBefore() {
53-
}
59+
protected void printThisBefore() {
60+
}
5461

55-
protected void printThisAfter() {
56-
}
62+
protected void printThisAfter() {
63+
}
5764

58-
public void print() {
59-
printThisBefore();
60-
children.forEach(LetterComposite::print);
61-
printThisAfter();
62-
}
65+
public void print() {
66+
printThisBefore();
67+
children.forEach(LetterComposite::print);
68+
printThisAfter();
69+
}
6370
}
6471

6572
public class Letter extends LetterComposite {
6673

67-
private final char character;
74+
private final char character;
6875

69-
public Letter(char c) {
70-
this.character = c;
71-
}
76+
public Letter(char c) {
77+
this.character = c;
78+
}
7279

73-
@Override
74-
protected void printThisBefore() {
75-
System.out.print(character);
76-
}
80+
@Override
81+
protected void printThisBefore() {
82+
System.out.print(character);
83+
}
7784
}
7885

7986
public class Word extends LetterComposite {
8087

81-
public Word(List<Letter> letters) {
82-
letters.forEach(this::add);
83-
}
88+
public Word(List<Letter> letters) {
89+
letters.forEach(this::add);
90+
}
8491

85-
public Word(char... letters) {
86-
for (char letter : letters) {
87-
this.add(new Letter(letter));
92+
public Word(char... letters) {
93+
for (char letter : letters) {
94+
this.add(new Letter(letter));
95+
}
8896
}
89-
}
9097

91-
@Override
92-
protected void printThisBefore() {
93-
System.out.print(" ");
94-
}
98+
@Override
99+
protected void printThisBefore() {
100+
System.out.print(" ");
101+
}
95102
}
96103

97104
public class Sentence extends LetterComposite {
98105

99-
public Sentence(List<Word> words) {
100-
words.forEach(this::add);
101-
}
106+
public Sentence(List<Word> words) {
107+
words.forEach(this::add);
108+
}
102109

103-
@Override
104-
protected void printThisAfter() {
105-
System.out.print(".");
106-
}
110+
@Override
111+
protected void printThisAfter() {
112+
System.out.print(".");
113+
}
107114
}
108115
```
109116

@@ -112,52 +119,52 @@ Then we have a messenger to carry messages:
112119
```java
113120
public class Messenger {
114121

115-
LetterComposite messageFromOrcs() {
122+
LetterComposite messageFromOrcs() {
116123

117-
var words = List.of(
118-
new Word('W', 'h', 'e', 'r', 'e'),
119-
new Word('t', 'h', 'e', 'r', 'e'),
120-
new Word('i', 's'),
121-
new Word('a'),
122-
new Word('w', 'h', 'i', 'p'),
123-
new Word('t', 'h', 'e', 'r', 'e'),
124-
new Word('i', 's'),
125-
new Word('a'),
126-
new Word('w', 'a', 'y')
127-
);
124+
var words = List.of(
125+
new Word('W', 'h', 'e', 'r', 'e'),
126+
new Word('t', 'h', 'e', 'r', 'e'),
127+
new Word('i', 's'),
128+
new Word('a'),
129+
new Word('w', 'h', 'i', 'p'),
130+
new Word('t', 'h', 'e', 'r', 'e'),
131+
new Word('i', 's'),
132+
new Word('a'),
133+
new Word('w', 'a', 'y')
134+
);
128135

129-
return new Sentence(words);
136+
return new Sentence(words);
130137

131-
}
138+
}
132139

133-
LetterComposite messageFromElves() {
140+
LetterComposite messageFromElves() {
134141

135-
var words = List.of(
136-
new Word('M', 'u', 'c', 'h'),
137-
new Word('w', 'i', 'n', 'd'),
138-
new Word('p', 'o', 'u', 'r', 's'),
139-
new Word('f', 'r', 'o', 'm'),
140-
new Word('y', 'o', 'u', 'r'),
141-
new Word('m', 'o', 'u', 't', 'h')
142-
);
142+
var words = List.of(
143+
new Word('M', 'u', 'c', 'h'),
144+
new Word('w', 'i', 'n', 'd'),
145+
new Word('p', 'o', 'u', 'r', 's'),
146+
new Word('f', 'r', 'o', 'm'),
147+
new Word('y', 'o', 'u', 'r'),
148+
new Word('m', 'o', 'u', 't', 'h')
149+
);
143150

144-
return new Sentence(words);
151+
return new Sentence(words);
145152

146-
}
153+
}
147154

148155
}
149156
```
150157

151158
And then it can be used as:
152159

153160
```java
154-
var messenger = new Messenger();
161+
var messenger=new Messenger();
155162

156-
LOGGER.info("Message from the orcs: ");
157-
messenger.messageFromOrcs().print();
163+
LOGGER.info("Message from the orcs: ");
164+
messenger.messageFromOrcs().print();
158165

159-
LOGGER.info("Message from the elves: ");
160-
messenger.messageFromElves().print();
166+
LOGGER.info("Message from the elves: ");
167+
messenger.messageFromElves().print();
161168
```
162169

163170
The console output:
@@ -178,16 +185,44 @@ Message from the elves:
178185
Use the Composite pattern when
179186

180187
* You want to represent part-whole hierarchies of objects.
181-
* You want clients to be able to ignore the difference between compositions of objects and
182-
individual objects. Clients will treat all objects in the composite structure uniformly.
188+
* You want clients to be able to ignore the difference between compositions of objects and
189+
individual objects. Clients will treat all objects in the composite structure uniformly.
183190

184191
## Known uses
185192

186-
* [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)
187-
* [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)
193+
* Graphical user interfaces where components can contain other components (e.g., panels containing buttons, labels,
194+
other panels).
195+
* File system representations where directories can contain files and other directories.
196+
* Organizational structures where a department can contain sub-departments and employees.
197+
* [java.awt.Container](http://docs.oracle.com/javase/8/docs/api/java/awt/Container.html)
198+
and [java.awt.Component](http://docs.oracle.com/javase/8/docs/api/java/awt/Component.html)
199+
* [Apache Wicket](https://github.com/apache/wicket) component tree,
200+
see [Component](https://github.com/apache/wicket/blob/91e154702ab1ff3481ef6cbb04c6044814b7e130/wicket-core/src/main/java/org/apache/wicket/Component.java)
201+
and [MarkupContainer](https://github.com/apache/wicket/blob/b60ec64d0b50a611a9549809c9ab216f0ffa3ae3/wicket-core/src/main/java/org/apache/wicket/MarkupContainer.java)
202+
203+
## Consequences
204+
205+
Benefits:
206+
207+
* Simplifies client code, as it can treat composite structures and individual objects uniformly.
208+
* Makes it easier to add new kinds of components, as existing code doesn't need to be changed.
209+
210+
Trade-offs:
211+
212+
* Can make the design overly general. It might be difficult to restrict the components of a composite.
213+
* Can make it harder to restrict the types of components in a composite.
214+
215+
## Related Patterns
216+
217+
* [Flyweight](https://java-design-patterns.com/patterns/flyweight/): Composite can use Flyweight to share component
218+
instances among several composites.
219+
* [Iterator](https://java-design-patterns.com/patterns/iterator/): Can be used to traverse Composite structures.
220+
* [Visitor](https://java-design-patterns.com/patterns/visitor/): Can apply an operation over a Composite structure.
188221

189222
## Credits
190223

191224
* [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)
192225
* [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)
193226
* [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)
227+
* [Pattern-Oriented Software Architecture, Volume 1: A System of Patterns](https://amzn.to/3xoLAmi)
228+
* [Patterns of Enterprise Application Architecture](https://amzn.to/3vBKXWb)

0 commit comments

Comments
 (0)