Composite Pattern, also known as partial overall pattern, is used to treat a group of similar objects as a single object. The combination mode combines objects according to the tree structure, which is used to represent the partial and overall levels. This type of design pattern belongs to structural pattern, which creates a tree structure of object groups. This pattern creates a class that contains its own group of objects. This class provides a way to modify the same object group.
Intent: combine objects into a tree structure to represent a "part whole" hierarchy. The combination mode enables users to use single objects and combined objects consistently.
Main solution: in our tree structure problem, it blurs the concepts of simple elements and complex elements. The client program can deal with complex elements as simple elements, so as to decouple the internal structure of the client program and complex elements.
When to use: 1. You want to represent the part of the object - the overall hierarchy (tree structure). 2. You want users to ignore the difference between composite objects and individual objects, and users will use all objects in the composite structure uniformly.
How to solve: the branch and leaf realize a unified interface, and the interface is combined inside the branch.
Key code: the interface is combined inside the tree branch, and contains the internal attribute List with Component inside.
Application examples: 1. Arithmetic expressions include operands, operators and another operand. The other operand can also be operands, operators and another operand.
Advantages: 1. Simple calling of high-level modules. 2. Nodes increase freely.
Disadvantages: when using composite mode, the declarations of its leaves and branches are implementation classes rather than interfaces, which violates the dependency inversion principle.
Usage scenario: partial and overall scenarios, such as tree menu, file and folder management.
Note: it is defined as a specific class.
The typical structure diagram of Composite mode is:
Complete code example
Component.h
#ifndef _COMPONENT_H_ #define _COMPONENT_H_ class Component { public: Component(); virtual ~Component(); public: virtual void Operation() = 0; virtual void Add(const Component& ); virtual void Remove(const Component& ); virtual Component* GetChild(int ); protected: private: }; #endif //~_COMPONENT_H_
Component.cpp
#include "Component.h" Component::Component() { } Component::~Component() { } void Component::Add(const Component& com) { } Component* Component::GetChild(int index) { return 0; } void Component::Remove(const Component& com) { }
Composite.h
#ifndef _COMPOSITE_H_ #define _COMPOSITE_H_ #include "Component.h" #include <vector> using namespace std; class Composite:public Component { public: Composite(); ~Composite(); public: void Operation(); void Add(Component* com); void Remove(Component* com); Component* GetChild(int index); protected: private: vector<Component*> comVec; }; #endif //~_COMPOSITE_H_
Composite.cpp
#include "Composite.h" #include "Component.h" #define NULL 0 //define NULL POINTOR Composite::Composite() { //vector<Component*>::iterator itend = comVec.begin(); } Composite::~Composite() { } void Composite::Operation() { vector<Component*>::iterator comIter = comVec.begin(); for (;comIter != comVec.end();comIter++) { (*comIter)->Operation(); } } void Composite::Add(Component* com) { comVec.push_back(com); } void Composite::Remove(Component* com) { comVec.erase(&com); } Component* Composite::GetChild(int index) { return comVec[index]; }
Leaf.h
#ifndef _LEAF_H_ #define _LEAF_H_ #include "Component.h" class Leaf:public Component { public: Leaf(); ~Leaf(); void Operation(); protected: private: }; #endif //~_LEAF_H_
Leaf.cpp
#include "Leaf.h" #include <iostream> using namespace std; Leaf::Leaf() { } Leaf::~Leaf() { } void Leaf::Operation() { cout<<"Leaf operation....."<<endl; }
main.cpp
#include "Component.h" #include "Composite.h" #include "Leaf.h" #include <iostream> using namespace std; int main(int argc,char* argv[]) { Leaf* l = new Leaf(); l->Operation(); Composite* com = new Composite(); com->Add(l); com->Operation(); Component* ll = com->GetChild(0); ll->Operation(); return 0; }
One problem in the implementation of Composite mode is to provide the management strategy for child nodes (leaves). Here, the vector in STL is used, which can provide other implementation methods, such as array, linked list, Hash table, etc.