当前位置:网站首页>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 .
边栏推荐
- 两道面试小Demo
- SQL 优化经历:从 30248秒到 0.001秒的经历
- Play SFTP upload file
- The digital human industry is about to break out. What is the market pattern?
- Campus honey decoration of APP course design (e-commerce platform)
- What is online account opening? Is it safe to open an account online now?
- Linux下安装redis 、Windows下安装redis(超详细图文教程)
- 剑指Offer | 链表转置
- Regular verification of mobile phone number and email [easy to understand]
- 异常的产生,及解决
猜你喜欢

For the development of short video app, the elder warned me to choose the open source code

Why does select * lead to low query efficiency?

Stock suspension

redis5.0的槽点迁移,随意玩(单机迁移集群)

Dbeaver连接人大金仓KingbaseES V8(超详细图文教程)

Illustration of MySQL binlog, redo log and undo log

1182: effets de la photo de groupe
![[ybtoj advanced training guide] maximum separation [hash] [Floyd]](/img/86/542ab1728a2ddbc01592b2fa83491a.jpg)
[ybtoj advanced training guide] maximum separation [hash] [Floyd]

JVM系列(2)——垃圾回收

Key summary V of PMP examination - execution process group
随机推荐
PMP Exam key summary VI - chart arrangement
104. maximum depth of binary tree
Key summary IV of PMP examination - planning process group (2)
自定义异常类及练习
Dolphin scheduler uses system time
Fastjason filter field
PMP考试重点总结七——监控过程组(1)
2020-10-27
Data visualization makes correlation analysis easier to use
SQL 优化经历:从 30248秒到 0.001秒的经历
函数的分文件编写
线程的生命周期
DBeaver安装与使用教程(超详细安装与使用教程)
How to reduce the risk of project communication?
[ybtoj advanced training guide] maximum separation [hash] [Floyd]
flink cep 跳过策略 AfterMatchSkipStrategy.skipPastLastEvent() 匹配过的不再匹配 碧坑指南
全局异常处理器与统一返回结果
优秀笔记软件盘点:好看且强大的可视化笔记软件、知识图谱工具Heptabase、氢图、Walling、Reflect、InfraNodus、TiddlyWiki
Redis5.0 slot migration, free play (single machine migration cluster)
new URL(“www.jjj.com“)