Skip to content

Commit f28ed7b

Browse files
committed
iluwatar#590 Add explanation for Composite pattern
1 parent 7f1fac0 commit f28ed7b

File tree

11 files changed

+117
-139
lines changed

11 files changed

+117
-139
lines changed

Diff for: composite/README.md

+113-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,119 @@ Compose objects into tree structures to represent part-whole
1616
hierarchies. Composite lets clients treat individual objects and compositions
1717
of objects uniformly.
1818

19-
![alt text](./etc/composite_1.png "Composite")
19+
## Explanation
20+
21+
Real world example
22+
23+
> Every sentence is composed of words which are in turn composed of characters. Each of these objects is 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
24+
25+
In plain words
26+
27+
> Composite pattern lets clients treat the individual objects in a uniform manner.
28+
29+
Wikipedia says
30+
31+
> 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.
32+
33+
**Programmatic Example**
34+
35+
Taking our sentence example from above. Here we have the base class and different printable types
36+
37+
```
38+
public abstract class LetterComposite {
39+
private List<LetterComposite> children = new ArrayList<>();
40+
public void add(LetterComposite letter) {
41+
children.add(letter);
42+
}
43+
public int count() {
44+
return children.size();
45+
}
46+
protected void printThisBefore() {}
47+
protected void printThisAfter() {}
48+
public void print() {
49+
printThisBefore();
50+
for (LetterComposite letter : children) {
51+
letter.print();
52+
}
53+
printThisAfter();
54+
}
55+
}
56+
57+
public class Letter extends LetterComposite {
58+
private char c;
59+
public Letter(char c) {
60+
this.c = c;
61+
}
62+
@Override
63+
protected void printThisBefore() {
64+
System.out.print(c);
65+
}
66+
}
67+
68+
public class Word extends LetterComposite {
69+
public Word(List<Letter> letters) {
70+
for (Letter l : letters) {
71+
this.add(l);
72+
}
73+
}
74+
@Override
75+
protected void printThisBefore() {
76+
System.out.print(" ");
77+
}
78+
}
79+
80+
public class Sentence extends LetterComposite {
81+
public Sentence(List<Word> words) {
82+
for (Word w : words) {
83+
this.add(w);
84+
}
85+
}
86+
@Override
87+
protected void printThisAfter() {
88+
System.out.print(".");
89+
}
90+
}
91+
```
92+
93+
Then we have a messenger to carry messages
94+
95+
```
96+
public class Messenger {
97+
LetterComposite messageFromOrcs() {
98+
List<Word> words = new ArrayList<>();
99+
words.add(new Word(Arrays.asList(new Letter('W'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e'))));
100+
words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e'))));
101+
words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s'))));
102+
words.add(new Word(Arrays.asList(new Letter('a'))));
103+
words.add(new Word(Arrays.asList(new Letter('w'), new Letter('h'), new Letter('i'), new Letter('p'))));
104+
words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e'))));
105+
words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s'))));
106+
words.add(new Word(Arrays.asList(new Letter('a'))));
107+
words.add(new Word(Arrays.asList(new Letter('w'), new Letter('a'), new Letter('y'))));
108+
return new Sentence(words);
109+
}
110+
111+
LetterComposite messageFromElves() {
112+
List<Word> words = new ArrayList<>();
113+
words.add(new Word(Arrays.asList(new Letter('M'), new Letter('u'), new Letter('c'), new Letter('h'))));
114+
words.add(new Word(Arrays.asList(new Letter('w'), new Letter('i'), new Letter('n'), new Letter('d'))));
115+
words.add(new Word(Arrays.asList(new Letter('p'), new Letter('o'), new Letter('u'), new Letter('r'), new Letter('s'))));
116+
words.add(new Word(Arrays.asList(new Letter('f'), new Letter('r'), new Letter('o'), new Letter('m'))));
117+
words.add(new Word(Arrays.asList(new Letter('y'), new Letter('o'), new Letter('u'), new Letter('r'))));
118+
words.add(new Word(Arrays.asList(new Letter('m'), new Letter('o'), new Letter('u'), new Letter('t'), new Letter('h'))));
119+
return new Sentence(words);
120+
}
121+
}
122+
```
123+
124+
And then it can be used as
125+
126+
```
127+
LetterComposite orcMessage = new Messenger().messageFromOrcs();
128+
orcMessage.print(); // Where there is a whip there is a way.
129+
LetterComposite elfMessage = new Messenger().messageFromElves();
130+
elfMessage.print(); // Much wind pours from your mouth.
131+
```
20132

21133
## Applicability
22134
Use the Composite pattern when

Diff for: composite/etc/composite.png

-15.8 KB
Binary file not shown.

Diff for: composite/etc/composite.ucls

-75
This file was deleted.

Diff for: composite/etc/composite.urm.puml

-43
This file was deleted.

Diff for: composite/etc/composite_1.png

-33.1 KB
Binary file not shown.

Diff for: composite/src/main/java/com/iluwatar/composite/App.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ public static void main(String[] args) {
5151
LetterComposite orcMessage = new Messenger().messageFromOrcs();
5252
orcMessage.print();
5353

54-
LOGGER.info("\n");
55-
56-
LOGGER.info("Message from the elves: ");
54+
LOGGER.info("\nMessage from the elves: ");
5755

5856
LetterComposite elfMessage = new Messenger().messageFromElves();
5957
elfMessage.print();

Diff for: composite/src/main/java/com/iluwatar/composite/Letter.java

-5
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,4 @@ public Letter(char c) {
3939
protected void printThisBefore() {
4040
System.out.print(c);
4141
}
42-
43-
@Override
44-
protected void printThisAfter() {
45-
// nop
46-
}
4742
}

Diff for: composite/src/main/java/com/iluwatar/composite/LetterComposite.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ public int count() {
4242
return children.size();
4343
}
4444

45-
protected abstract void printThisBefore();
45+
protected void printThisBefore() {}
4646

47-
protected abstract void printThisAfter();
47+
protected void printThisAfter() {}
4848

4949
/**
5050
* Print

Diff for: composite/src/main/java/com/iluwatar/composite/Sentence.java

-5
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ public Sentence(List<Word> words) {
4040
}
4141
}
4242

43-
@Override
44-
protected void printThisBefore() {
45-
// nop
46-
}
47-
4843
@Override
4944
protected void printThisAfter() {
5045
System.out.print(".");

Diff for: composite/src/main/java/com/iluwatar/composite/Word.java

-5
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,4 @@ public Word(List<Letter> letters) {
4444
protected void printThisBefore() {
4545
System.out.print(" ");
4646
}
47-
48-
@Override
49-
protected void printThisAfter() {
50-
// nop
51-
}
5247
}

Diff for: pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@
468468
<param>prototype</param>
469469
<param>adapter</param>
470470
<param>bridge</param>
471+
<param>composite</param>
471472
</skipForProjects>
472473
</configuration>
473474
</plugin>

0 commit comments

Comments
 (0)