组合模式(c++实现)
组合模式
定义
将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式是的用户对单个对象和组合对象的使用具有一致性。
动机
当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一的使用组合对象结构中的所有对象时,就应该考虑用组合模式了。
UML类图
场景拆解
以一个大型公司为需求背景,组织我们的代码。一个北京总公司,下面有郑州和西安两个分公司。然后每个公司不管是总公司还是分公司都有自己的人力资源部,IT部和市场部。
源码实现
- 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 : 安排一下故事背景:有一个王者农药全国总公司在深圳,现在想要在全国开办事处
* 1.北京办事处- 招聘部,研发部,市场部
* 2.郑州办事处- 招聘部,研发部,市场部
* 3.西安办事处- 招聘部,研发部,市场部
* 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() << "人力资源部,负责招聘";
}
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部门,负责写代码";
}
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() << "市场部门,负责市场推广";
}
- main.cpp
#include <QCoreApplication>
#include <QDebug>
#include "component.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Component* root = new ConcreteCompany("北京总部");
root->setDepth(0);
root->add(new HumanResource("人力资源部门"), 1);
root->add(new IT("IT部门"), 1);
root->add(new Marketing("市场部门"), 1);
Component* zz = new ConcreteCompany("郑州办事处");
zz->add(new HumanResource("人力资源部门"), 2);
zz->add(new IT("IT部门"), 2);
zz->add(new Marketing("市场部门"), 2);
root->add(zz, 1);
Component* xa = new ConcreteCompany("西安办事处");
xa->add(new HumanResource("人力资源部门"), 2);
xa->add(new IT("IT部门"), 2);
xa->add(new Marketing("市场部门"), 2);
root->add(xa, 1);
root->display();
return a.exec();
}
- 运行结果
"北京总部"
-- "人力资源部门"
-- "IT部门"
-- "市场部门"
-- "郑州办事处"
---- "人力资源部门"
---- "IT部门"
---- "市场部门"
-- "西安办事处"
---- "人力资源部门"
---- "IT部门"
---- "市场部门"
优点
组合模式定义了包含基本对象和组合对象的类层次结构。基本对象可以组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象了。
缺点
参考《大化设计模式》
组合模式(c++实现)的更多相关文章
- ComponentPattern (组合模式)
import java.util.LinkedList; /** * 组合模式 * * @author TMAC-J 主要用于树状结构,用于部分和整体区别无区别的场景 想象一下,假设有一批连锁的理发店 ...
- 设计模式(十一):从文Finder中认识"组合模式"(Composite Pattern)
上一篇博客中我们从从电影院中认识了"迭代器模式"(Iterator Pattern),今天我们就从文件系统中来认识一下“组合模式”(Composite Pattern).说到组合模 ...
- 设计模式(十)组合模式(Composite Pattern)
一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...
- 设计模式--组合模式Composite(结构型)
一.概念 组合模式允许你将对象组合成树形结构来表现"整体/部分"层次结构.组合能让客户以一致的方式处理个别对象以及对象组合. 二.UML图 1.Component(对象接口),定义 ...
- 组合模式/composite模式/对象结构型模式
组合模式/composite模式/对象结构型 意图 将对象组合成树形结构以表示"整体--部分"的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. 动机 C ...
- c#设计模式-组合模式
在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象和复合对象 ...
- C#设计模式系列:组合模式(Composite)
1.组合模式简介 1.1>.定义 组合模式主要用来处理一类具有“容器特征”的对象——即它们在充当对象的同时,又可以作为容器包含其他多个对象. 1.2>.使用频率 中高 2.组合模式结构图 ...
- php实现设计模式之 组合模式
<?php /** * 组合模式 * * 将对象组合成树形结构以表示"部分-整体"的层次结构,使得客户对单个对象和复合对象的使用具有一致性 * * * 1) 抽象构件角色Co ...
- 轻松掌握:JavaScript组合模式
组合模式 组合模式:将一组对象组合成树形结构,并统一对待组合对象和叶对象,忽略它们之间的不同(因为叶对象也可以也可以包含叶对象而成为组合对象),组合模式中的对象只能是一对多的关系,不能出现多对一. 基 ...
- java设计模式之组合模式
组合模式 组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性.掌握组合模式的重点是要理解清楚 “部分/整体” 还有 ”单个对象“ 与 & ...
随机推荐
- 【draft】Team project :Bing dictionary plug-in
课后~ 开会调研开会调研开会~ 在和Bing词典负责人进行了可行性的深入磋商后,我们对本次选题有了更加清晰的认识~困难好多~然而终于敲定了项目内容,我们的目标是这样一款神奇的插件,它帮你记录下新近查询 ...
- 关于C++线程池的实现的思考
今天突然对前些日子一直很疑惑的c++线程池有了新的想法.其实所谓的线程池无非就是两个技术点,一个,多线程,指工作线程和主线程分离,或者说数据接收和处理分两个线程,一般就是讲需要运行的函数放到子线程执行 ...
- 关于Python+selenium 定位浏览器弹窗元素
首先要确定弹窗的类型: (1)div弹窗 (2)新标签页弹窗 (3)alert弹窗 一,div弹窗div弹窗是浏览器中比较好定位的弹窗,定位的方法与普通的元素一样.不过这里会有一个坑,明明可以找到这个 ...
- python web的进化历程
对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. 阶段1 socket服务端和客户端都自己编写 实现访问8080端口,返回一个'hello wo ...
- Mysql数据操作指令
-----多数据插入-----只要写一次insert指令,但是可以直接插入多条记录insert into table values(),(),(); 主键冲突我们插入值的时候,主键中已经存在某个值,插 ...
- ambarella H2平台fpga捕捉卡驱动案例
公司最近开发的一款产品用到了ambarella H2平台的一款Soc,众所周知ambarella的H2系列的Soc编码能力很强,最高可达4kp60,捕捉上没有用ambarella开发板推荐的几个捕捉卡 ...
- thinkphp--create()的使用方法(个人感悟)
M方法和D方法的区别 ThinkPHP 中M方法和D方法都用于实例化一个模型类,M方法 用于高效实例化一个基础模型类,而 D方法 用于实例化一个用户定义模型类. 使用M方法 如果是如下情况,请考虑使用 ...
- thinkphp5 input坑
取值方式改了而已?a1=1&a2=2这种可以用input(get.) a1/1/a2/2 用input('a1')和input('a2') post方法当然是input('post.') 我觉 ...
- Nagios基本搭建
Nagios简述: 1.一款用来监视系统和网络的开源软件 2.利用其从多的插件实现对本机和远端服务的监控 3.当被监控对象异常时,回及时向管理员警告 4.提供一批预设好的监控插件,用户可以直接调用 5 ...
- Inno Setup 升级时不再询问用户安装路径
UsePreviousAppDir Description: When this directive is yes, the default, at startup Setup will look i ...