diff --git a/composite/README.md b/composite/README.md index fce6ed6af..fbb21ecb3 100644 --- a/composite/README.md +++ b/composite/README.md @@ -16,7 +16,119 @@ Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. -![alt text](./etc/composite_1.png "Composite") +## Explanation + +Real world example + +> 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 + +In plain words + +> Composite pattern lets clients treat the individual objects in a uniform manner. + +Wikipedia says + +> 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. + +**Programmatic Example** + +Taking our sentence example from above. Here we have the base class and different printable types + +``` +public abstract class LetterComposite { + private List children = new ArrayList<>(); + public void add(LetterComposite letter) { + children.add(letter); + } + public int count() { + return children.size(); + } + protected void printThisBefore() {} + protected void printThisAfter() {} + public void print() { + printThisBefore(); + for (LetterComposite letter : children) { + letter.print(); + } + printThisAfter(); + } +} + +public class Letter extends LetterComposite { + private char c; + public Letter(char c) { + this.c = c; + } + @Override + protected void printThisBefore() { + System.out.print(c); + } +} + +public class Word extends LetterComposite { + public Word(List letters) { + for (Letter l : letters) { + this.add(l); + } + } + @Override + protected void printThisBefore() { + System.out.print(" "); + } +} + +public class Sentence extends LetterComposite { + public Sentence(List words) { + for (Word w : words) { + this.add(w); + } + } + @Override + protected void printThisAfter() { + System.out.print("."); + } +} +``` + +Then we have a messenger to carry messages + +``` +public class Messenger { + LetterComposite messageFromOrcs() { + List words = new ArrayList<>(); + words.add(new Word(Arrays.asList(new Letter('W'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e')))); + words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e')))); + words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s')))); + words.add(new Word(Arrays.asList(new Letter('a')))); + words.add(new Word(Arrays.asList(new Letter('w'), new Letter('h'), new Letter('i'), new Letter('p')))); + words.add(new Word(Arrays.asList(new Letter('t'), new Letter('h'), new Letter('e'), new Letter('r'), new Letter('e')))); + words.add(new Word(Arrays.asList(new Letter('i'), new Letter('s')))); + words.add(new Word(Arrays.asList(new Letter('a')))); + words.add(new Word(Arrays.asList(new Letter('w'), new Letter('a'), new Letter('y')))); + return new Sentence(words); + } + + LetterComposite messageFromElves() { + List words = new ArrayList<>(); + words.add(new Word(Arrays.asList(new Letter('M'), new Letter('u'), new Letter('c'), new Letter('h')))); + words.add(new Word(Arrays.asList(new Letter('w'), new Letter('i'), new Letter('n'), new Letter('d')))); + words.add(new Word(Arrays.asList(new Letter('p'), new Letter('o'), new Letter('u'), new Letter('r'), new Letter('s')))); + words.add(new Word(Arrays.asList(new Letter('f'), new Letter('r'), new Letter('o'), new Letter('m')))); + words.add(new Word(Arrays.asList(new Letter('y'), new Letter('o'), new Letter('u'), new Letter('r')))); + words.add(new Word(Arrays.asList(new Letter('m'), new Letter('o'), new Letter('u'), new Letter('t'), new Letter('h')))); + return new Sentence(words); + } +} +``` + +And then it can be used as + +``` +LetterComposite orcMessage = new Messenger().messageFromOrcs(); +orcMessage.print(); // Where there is a whip there is a way. +LetterComposite elfMessage = new Messenger().messageFromElves(); +elfMessage.print(); // Much wind pours from your mouth. +``` ## Applicability Use the Composite pattern when diff --git a/composite/etc/composite.png b/composite/etc/composite.png deleted file mode 100644 index 1e6e6258a..000000000 Binary files a/composite/etc/composite.png and /dev/null differ diff --git a/composite/etc/composite.ucls b/composite/etc/composite.ucls deleted file mode 100644 index 184c452f4..000000000 --- a/composite/etc/composite.ucls +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/composite/etc/composite.urm.puml b/composite/etc/composite.urm.puml deleted file mode 100644 index 82f2cab0d..000000000 --- a/composite/etc/composite.urm.puml +++ /dev/null @@ -1,43 +0,0 @@ -@startuml -package com.iluwatar.composite { - class App { - - LOGGER : Logger {static} - + App() - + main(args : String[]) {static} - } - class Letter { - - c : char - + Letter(c : char) - # printThisAfter() - # printThisBefore() - } - abstract class LetterComposite { - - children : List - + LetterComposite() - + add(letter : LetterComposite) - + count() : int - + print() - # printThisAfter() {abstract} - # printThisBefore() {abstract} - } - class Messenger { - + Messenger() - ~ messageFromElves() : LetterComposite - ~ messageFromOrcs() : LetterComposite - } - class Sentence { - + Sentence(words : List) - # printThisAfter() - # printThisBefore() - } - class Word { - + Word(letters : List) - # printThisAfter() - # printThisBefore() - } -} -LetterComposite --> "-children" LetterComposite -Letter --|> LetterComposite -Sentence --|> LetterComposite -Word --|> LetterComposite -@enduml \ No newline at end of file diff --git a/composite/etc/composite_1.png b/composite/etc/composite_1.png deleted file mode 100644 index 5f5b010dd..000000000 Binary files a/composite/etc/composite_1.png and /dev/null differ diff --git a/composite/src/main/java/com/iluwatar/composite/App.java b/composite/src/main/java/com/iluwatar/composite/App.java index 5d725c082..517920ac6 100644 --- a/composite/src/main/java/com/iluwatar/composite/App.java +++ b/composite/src/main/java/com/iluwatar/composite/App.java @@ -51,9 +51,7 @@ public class App { LetterComposite orcMessage = new Messenger().messageFromOrcs(); orcMessage.print(); - LOGGER.info("\n"); - - LOGGER.info("Message from the elves: "); + LOGGER.info("\nMessage from the elves: "); LetterComposite elfMessage = new Messenger().messageFromElves(); elfMessage.print(); diff --git a/composite/src/main/java/com/iluwatar/composite/Letter.java b/composite/src/main/java/com/iluwatar/composite/Letter.java index 036854f5d..cd149122d 100644 --- a/composite/src/main/java/com/iluwatar/composite/Letter.java +++ b/composite/src/main/java/com/iluwatar/composite/Letter.java @@ -39,9 +39,4 @@ public class Letter extends LetterComposite { protected void printThisBefore() { System.out.print(c); } - - @Override - protected void printThisAfter() { - // nop - } } diff --git a/composite/src/main/java/com/iluwatar/composite/LetterComposite.java b/composite/src/main/java/com/iluwatar/composite/LetterComposite.java index c7c1344a0..f9ff68463 100644 --- a/composite/src/main/java/com/iluwatar/composite/LetterComposite.java +++ b/composite/src/main/java/com/iluwatar/composite/LetterComposite.java @@ -42,9 +42,9 @@ public abstract class LetterComposite { return children.size(); } - protected abstract void printThisBefore(); + protected void printThisBefore() {} - protected abstract void printThisAfter(); + protected void printThisAfter() {} /** * Print diff --git a/composite/src/main/java/com/iluwatar/composite/Sentence.java b/composite/src/main/java/com/iluwatar/composite/Sentence.java index e83406619..ae844cf59 100644 --- a/composite/src/main/java/com/iluwatar/composite/Sentence.java +++ b/composite/src/main/java/com/iluwatar/composite/Sentence.java @@ -40,11 +40,6 @@ public class Sentence extends LetterComposite { } } - @Override - protected void printThisBefore() { - // nop - } - @Override protected void printThisAfter() { System.out.print("."); diff --git a/composite/src/main/java/com/iluwatar/composite/Word.java b/composite/src/main/java/com/iluwatar/composite/Word.java index 1efc3465f..51e21a2d4 100644 --- a/composite/src/main/java/com/iluwatar/composite/Word.java +++ b/composite/src/main/java/com/iluwatar/composite/Word.java @@ -44,9 +44,4 @@ public class Word extends LetterComposite { protected void printThisBefore() { System.out.print(" "); } - - @Override - protected void printThisAfter() { - // nop - } } diff --git a/pom.xml b/pom.xml index 06148064f..6212ddc05 100644 --- a/pom.xml +++ b/pom.xml @@ -468,6 +468,7 @@ prototype adapter bridge + composite