当前位置:网站首页>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 .
边栏推荐
- PMP Exam key summary VI - chart arrangement
- 结巴分词器_分词器原理
- Thread lifecycle
- Stutter participle_ Principle of word breaker
- 构造方法绝不是在new()之后就立马执行!!!!!
- Understanding the IO model
- Unity AssetBundle资源打包与资源加载
- Virtual machine 14 installing win7 (Figure tutorial)
- RESTful风格
- Ingersoll Rand panel maintenance IR Ingersoll Rand microcomputer controller maintenance xe-145m
猜你喜欢

全局异常处理器与统一返回结果

Boundary value analysis method for learning basic content of software testing (2)

SQL 优化经历:从 30248秒到 0.001秒的经历

PMP examination key summary VIII - monitoring process group (2)

1182: group photo effect

Valentine's Day - VBS learning (sentences, love words)

1182: effets de la photo de groupe

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

Prototype chain JS

Ingersoll Rand面板维修IR英格索兰微电脑控制器维修XE-145M
随机推荐
桥接模式(Bridge)
Ingersoll Rand面板维修IR英格索兰微电脑控制器维修XE-145M
Decision table method for basic content learning of software testing (2)
Basic content learning of software testing (I)
Explain final, finally, and finalize
Calcul des frais d'achat et de vente d'actions
new URL(“www.jjj.com“)
PMP Exam key summary VI - chart arrangement
Function sub file writing
A classic JVM class loaded interview question class singleton{static singleton instance = new singleton(); private singleton() {}
PMP考试重点总结九——收尾
PMP考试重点总结六——图表整理
June 27, 2022: give a 01 string with a length of N. now please find two intervals so that the number of 1 is equal and the number of 0 is equal in the two intervals. The two intervals can intersect bu
Summary of PMP learning experience
自动转换之-面试题
Scenario method and error recommendation method for learning basic content of software testing (2)
Stock suspension
File operations in QT
Learn how Alibaba manages the data indicator system
1182:合影效果