Composite Pattern
Composite Pattern에 대해 설명하는 페이지입니다.
Composite Pattern
Tags
Design Pattern, Java
1. Introduction
- Purpose
- Facilitates the creation of object hierarchies where each object can be treated independently or as a set of nested objects through the same interface.
- Use When
- Hierarchical representations of objects are needed.
- Objects and compositions of objects should be treated uniformly.
2. Characteristics
- composes objects into tree structures to represent whole-part hierarchies.
- lets clients treat individual objects and compositions of objects uniformly.
- Child Mgt. Interface
- Placing in Component class gives Transparency.
- since all components can be treated the same. However, it is not safe. Clients can try to do meaningless things to leaf components at run-time.
- Placing in Composite class gives Safety.
- since any attempt to perform a child operation on a leaf component will be caught at compile-time. However, we lose transparency because now leaf and composite components have different interfaces.
- Placing in Component class gives Transparency.
3. Related patterns
- Composite vs Decorator
- Both have similar structure diagrams
- recursive composition to organize an open-ended number of objects
- Different intentions
- Decorator lets you add responsibilities to objects without subclassing
- Composite's focus is not on embellishment but on representation
- They are complementary; hence, Composite and Decorator are often used in concert
- Both have similar structure diagrams
- Iterator
- Provide a way to access the elements of an aggregate object (=typically uses composite pattern) sequentially without exposing its underlying representation
4. How to Use (Example)
-
Component
java1public class Component { 2 public void add(Component component) { 3 throw new UnsupportedOperationException(); 4 } 5} -
Leaf
java1public class Leaf extends Component { 2 public String name; 3 public Leaf(String name) { 4 this.name = name; 5 } 6 public String getName() { 7 return name; 8 } 9 public Iterator createIterator() { 10 return new NullIterator(); 11 } 12}java1public class NullIterator implements Iterator { 2 public Object next() { 3 return null; 4 } 5 public boolean hasNext() { 6 return false; 7 } 8 public void remove() { 9 throw new UnsupportedOperationException(); 10 } 11} -
Composite
java1import java.util.ArrayList; 2 3public class Composite extends Component { 4 public String name; 5 public ArrayList<Component> components; 6 public Iterator iterator = null; 7 8 public Composite(String name) { 9 this.name = name; 10 components = new ArrayList<Component>(); 11 } 12 13 @Override 14 public void add(Component component) { 15 components.add(component); 16 } 17 18 public Iterator createIterator() { 19 if (iterator == null) { 20 iterator = new CompositeIterator(components.iterator()); 21 } 22 return iterator; 23 } 24}java1import java.util.Stack; 2 3public class CompositeIterator implements Iterator { 4 public Stack<Component> stack = new Stack<Component>(); 5 public CompositeIterator(Iterator iterator) { 6 stack.push(iterator); 7 } 8 public Object next() { 9 if (hasNext()) { 10 Iterator iterator = (Iterator) stack.peek(); 11 Component component = (Component) iterator.next(); 12 if (component instanceof Composite) { 13 stack.push(component.createIterator()); 14 } 15 return component; 16 } else { 17 return null; 18 } 19 } 20 public boolean hasNext() { 21 if (stack.empty()) { 22 return false; 23 } 24 Iterator iterator = (Iterator) stack.peek(); 25 if (!iterator.hasNext()) { 26 stack.pop(); 27 return hasNext(); 28 } else { 29 return true; 30 } 31 } 32 public void remove() { 33 throw new UnsupportedOperationException(); 34 } 35}
