Layering & Contract Philosophy With additional indirection
1 class CComponent 2 { 3 public: virtual void Operation() = 0; 4 public: virtual void AddComponent(Component* p)= 0; 5 public: virtual void RemoveComponent(Component* p)= 0; 6 public: virtual Component* GetChild(int i) { return NULL;} 7 } 8 class CComposite: public CComponent 9 { 10 public: virtual void Operation() 11 { foreach ( i ) GetChild(i)->Opeartion(); }; 12 public: virtual void AddComponent(Component* p) 13 { v.add( p );}; 14 public: virtual void RemoveComponent(Component* p) 15 { v.remove(p);} 16 public: virtual Component* GetChild(int i) 17 { return v[i];} 18 private: vector< CComponent* > v; 19 } 20 class CLeaf: public CCompoent 21 { 22 public: virtual void Operation() 23 { do_something_for_leaf(); }; 24 } 25 class Client 26 { 27 CLeaf* pleaf1 = new CLeaf; CLeaf* pleaf2 = new CLeaf; 28 CLeaf* pleaf3 = new CLeaf; CLeaf* pleaf4 = new CLeaf; 29 CLeaf* pleaf5 = new CLeaf; CLeaf* pleaf6 = new CLeaf; 30 CComposite* pcomposite1, pcomposite2 = new CComposite; 31 pcomposite1.addcomponent(pleaf1); 32 pcomposite1.addcomponent(pleaf2); 33 pcomposite1.addcomponent(pleaf3); 34 pcomposite2.addcomponent(pleaf4); 35 pcomposite2.addcomponent(pleaf5); 36 pcomposite2.addcomponent(pcomposite1); 37 CComposite* pAll = new CComposite; 38 pAll.addComponent(pcomposite1); 39 pAll.addComponent(pcomposite2); 40 pAll.addComponent(pleaf6); 41 pAll.Opearation(); 42 }
Applicability
Use the Composite pattern when:
- 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.
Participants
Component (Graphic)
- declares the interface for objects in the composition.
- implements default behavior for the interface common to all classes, as appropriate.
- declares an interface for accessing and managing its child components.
- (optional) defines an interface for accessing a component's parent in the recursive structure, and implements it if that's appropriate.
Leaf (Rectangle, Line, Text, etc.)
- represents leaf objects in the composition. A leaf has no children.
- defines behavior for primitive objects in the composition.
Composite (Picture)
- defines behavior for components having children.
- stores child components.
- implements child-related operations in the Component interface.
Client
- manipulates objects in the composition through the Component interface.
Collaborations
- Clients use the Component class interface to interact with objects in the composite structure. If the recipient is a Leaf, then the request is handled directly. If the recipient is a Composite, then it usually forwards requests to its child components, possibly performing additional operations before and/or after forwarding.