当前位置:网站首页>Composite pattern
Composite pattern
2022-06-28 09:39:00 【Beginner Xiaobai Lu】
Definition
Combine objects into a tree structure to represent “ part - whole ” Hierarchical structure . The composition mode makes the use of single object and composite object consistent .
motivation
When you find that the requirements are part and whole hierarchies , And you want users to ignore the difference between composite objects and individual objects , When using all objects in the composite object structure in a unified way , It's time to think about using a combination pattern .
UML Class diagram

- Component Abstract build roles , Define common methods and attributes that are exclusive to the portfolio , You can define some default behaviors or attributes
- Leaf Leaf structure , There are no branches , Is the smallest traversal unit
- Composite branch structure , It is a tree structure formed by combining branch nodes and leaf nodes
advantage
High level modules are easy to call , All nodes are Component , There is no difference between the part and the whole for the caller , The high level doesn't have to care whether they are dealing with a single object or the entire composite structure .
Nodes are increased freely , Using the composite pattern , If you want to add branch nodes , The nodes of leaves are easy , Just find the parent node , Comply with opening and closing principle .
shortcoming
Definition of branch and leaf nodes when used , The direct use is the implementation class . Against the principle of Dependence Inversion .
Use scenarios
Maintain and display a part - The whole relationship scenario :eg Tree menu , File and folder management .
Scenarios that can separate some modules and functions from a whole .
matters needing attention
As long as it's a tree structure , Consider the combination pattern , Just reflect this part of your relationship , Just use the composite pattern
Composite One problem in the implementation of pattern is to provide for child nodes ( Leaf) Management strategy , What we use here is STL Medium vector, Other implementations can be provided , Such as arrays 、 Linked list 、 Hash Table, etc .
Example

With a large company as the demand background , Organize our code . A Beijing head office , There are two branches in Zhengzhou and Xi'an . Then every company has its own human resources department, whether it is the head office or the branch office ,IT Department and marketing department .
// component.h
#ifndef COMPONENT_H
#define COMPONENT_H
#include <QList>
class Component
{
public:
Component(QString name);
virtual ~Component();
virtual void add(Component* com, int depth = 0) = 0;
virtual void remove(Component* com) = 0;
virtual void display() = 0;
virtual void LineOfDuty() = 0;
QString name();
void setDepth(int depth);
int depth();
private:
QString m_Name;
int m_Depth;
};
class ConcreteCompany : public Component
{
public:
ConcreteCompany(QString name);
virtual ~ConcreteCompany();
virtual void add(Component* com, int depth = 0);
virtual void remove(Component* com);
virtual void display();
virtual void LineOfDuty();
private:
QList<Component*> m_ChildCom;
};
class HumanResource : public Component
{
public:
HumanResource(QString name);
virtual ~HumanResource();
virtual void add(Component* com, int depth = 0);
virtual void remove(Component* com);
virtual void display();
virtual void LineOfDuty();
};
class IT : public Component
{
public:
IT(QString name);
virtual ~IT();
virtual void add(Component* com, int depth = 0);
virtual void remove(Component* com);
virtual void display();
virtual void LineOfDuty();
};
class Marketing : public Component
{
public:
Marketing(QString name);
virtual ~Marketing();
virtual void add(Component* com, int depth = 0);
virtual void remove(Component* com);
virtual void display();
virtual void LineOfDuty();
};
#endif // COMPONENT_H
// component.cpp
/************************************ * @brief : Set the story : There is a king pesticide National Corporation in Shenzhen , Now I want to open offices all over the country * 1. Beijing Office - Recruitment department , R & D department , The Marketing Department * 2. Zhengzhou office - Recruitment department , R & D department , The Marketing Department * 3. Xi'an Office - Recruitment department , R & D department , The Marketing Department * and so on... * @author : wzx * @date : 2020-05-11 * @project : Composite *************************************/
#include <QDebug>
#include "component.h"
#define DELETEOBJECT(x) if(x) {
delete x; x = nullptr; }
Component::Component(QString name):m_Name(name) {
}
Component::~Component(){
}
QString Component::name()
{
return m_Name;
}
void Component::setDepth(int depth)
{
m_Depth = depth;
}
int Component::depth()
{
return m_Depth;
}
ConcreteCompany::ConcreteCompany(QString name)
: Component(name)
{
}
ConcreteCompany::~ConcreteCompany()
{
for(auto com : m_ChildCom)
{
DELETEOBJECT(com);
}
m_ChildCom.clear();
}
void ConcreteCompany::add(Component* com, int depth)
{
com->setDepth(depth);
m_ChildCom.append(com);
}
void ConcreteCompany:: remove(Component* com)
{
m_ChildCom.removeOne(com);
}
void ConcreteCompany::display()
{
QString str;
for(int n = 0; n < depth(); ++n)
str += "--";
qDebug() << qPrintable(str) << (name());
for(auto com : m_ChildCom)
{
com->display();
}
}
void ConcreteCompany::LineOfDuty()
{
}
HumanResource::HumanResource(QString name)
: Component(name)
{
}
HumanResource::~HumanResource()
{
}
void HumanResource::add(Component* com, int depth)
{
com->setDepth(depth);
}
void HumanResource::remove(Component* com)
{
}
void HumanResource::display()
{
QString str;
for(int n = 0; n < depth(); ++n)
str += "--";
qDebug() << qPrintable(str) << (name());
}
void HumanResource::LineOfDuty()
{
qDebug() << " Human Resources Department , Responsible for recruitment ";
}
IT::IT(QString name)
: Component(name)
{
}
IT::~IT()
{
}
void IT::add(Component* com, int depth)
{
com->setDepth(depth);
}
void IT::remove(Component* com)
{
}
void IT::display()
{
QString str;
for(int n = 0; n < depth(); ++n)
str += "--";
qDebug() << qPrintable(str) << (name());
}
void IT::LineOfDuty()
{
qDebug() << "IT department , Responsible for writing code ";
}
Marketing::Marketing(QString name)
: Component(name)
{
}
Marketing::~Marketing()
{
}
void Marketing::add(Component* com, int depth)
{
com->setDepth(depth);
}
void Marketing::remove(Component* com)
{
}
void Marketing::display()
{
QString str;
for(int n = 0; n < depth(); ++n)
str += "--";
qDebug() << qPrintable(str) << name();
}
void Marketing::LineOfDuty()
{
qDebug() << " Marketing Department , Responsible for marketing ";
}
// main.cpp
#include <QCoreApplication>
#include <QDebug>
#include "component.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Component* root = new ConcreteCompany(" Beijing headquarters ");
root->setDepth(0);
root->add(new HumanResource(" Human Resources Department "), 1);
root->add(new IT("IT department "), 1);
root->add(new Marketing(" Marketing Department "), 1);
Component* zz = new ConcreteCompany(" Zhengzhou office ");
zz->add(new HumanResource(" Human Resources Department "), 2);
zz->add(new IT("IT department "), 2);
zz->add(new Marketing(" Marketing Department "), 2);
root->add(zz, 1);
Component* xa = new ConcreteCompany(" Xi'an Office ");
xa->add(new HumanResource(" Human Resources Department "), 2);
xa->add(new IT("IT department "), 2);
xa->add(new Marketing(" Marketing Department "), 2);
root->add(xa, 1);
root->display();
return a.exec();
}
Running results
" Beijing headquarters "
-- " Human Resources Department "
-- "IT department "
-- " Marketing Department "
-- " Zhengzhou office "
---- " Human Resources Department "
---- "IT department "
---- " Marketing Department "
-- " Xi'an Office "
---- " Human Resources Department "
---- "IT department "
---- " Marketing Department "
Example 2
Arithmetic expressions include operands 、 Operator and another operands , among , Another operand can also be an operand 、 Operator and another operands .
边栏推荐
- [ybtoj advanced training guidance] class roll call [string hash]
- 创建多线程的方法---1创建Thread类的子类及多线程原理
- SQL 优化经历:从 30248秒到 0.001秒的经历
- Music website design based on harmonyos (portal page)
- 代理模式(Proxy)
- 优秀笔记软件盘点:好看且强大的可视化笔记软件、知识图谱工具Heptabase、氢图、Walling、Reflect、InfraNodus、TiddlyWiki
- Which occupational groups are suitable for the examination
- 1182:合影效果
- JVM系列(2)——垃圾回收
- Unity 从服务器加载AssetBundle资源写入本地内存,并将下载保存的AB资源从本地内存加载至场景
猜你喜欢
随机推荐
Machine virtuelle 14 installer win7 (tutoriel)
P2394 yyy loves Chemistry I
1181:整数奇偶排序
Comprehensive evaluation of outline note taking software workflow: advantages, disadvantages and evaluation
创建多线程的方法---1创建Thread类的子类及多线程原理
两道面试小Demo
详解final、finally和finalize
4 methods for exception handling
Function sub file writing
Test cases for learning the basic content of software testing (II)
1180: fractional line delimitation /p1068 [noip2009 popularization group] fractional line delimitation
abnormal
Apache Doris becomes the top project of Apache
Calculation of stock purchase and sale expenses
Dbeaver connects to kingbasees V8 (ultra detailed graphic tutorial)
1181: integer parity sort
01 distributed system overview
Regular verification of mobile phone number and email [easy to understand]
结巴分词器_分词器原理
Importerror: no module named image [duplicate] - importerror: no module named image [duplicate]









