设计模式 --6组合模式

文章目录

    • 组合模式应用场景
    • 组合模式概念
    • 组合模式结构图
    • 透明方式和安全方式
    • 什么时候使用组合模式
    • 公司管理系统使用 组合模式来构架
    • 组合模式的好处

组合模式应用场景

整体和部分可以被一致性对待 比如人力资源部 财务部的管理功能可以复用于分公司的功能
可以引入一种 树状的结构 来统一管理

组合模式概念

组合模式(Composite),将对象组合成树形结构以表示“部分 - 整体” 的层次结构。组合模式是的用户对单个对象和组合对象的使用具有一致性。

组合模式结构图

在这里插入图片描述


#include <iostream>
#include <list>
using namespace std;//组合中对象声明接口 实现所有类共有的默认接口行为
class Component {
public:Component(string name){this->name = name;}virtual void Add(Component *c) {};virtual void Remove(Component* c) {};virtual void Display(int depth) {};//展示参数表示数的深度protected:string name;
};// 在组合里面表示叶子节点对象 叶节点没有子节点
class Leaf :public Component
{
public:Leaf(string name) :Component(name) {}void Add(Component* c) override {cout << "cannot add to a leaf " << endl;}void Remove(Component* c) override {cout << "cannot Remove from  a leaf " << endl;}void Display(int depth) override {string a = string(depth, '-');cout << a << name << endl;}};//在组合里面定义有子节点行为 用来存储子部件
class Composite : public Component
{
public:Composite(string name) :Component(name) {}void Add(Component *c) override {children.push_back(c);}void Remove(Component *c) override {children.remove(c);}void Display(int depth)override{cout << string(depth, '-') << name << endl;for (auto Com : children){Com->Display(depth + 2);}}private:list<Component*> children;
};int main()
{Composite * root = new Composite("root");root->Add(new Leaf("Leaf A"));root->Add(new Leaf("Leaf B"));Composite* comp = new Composite("Composite X");comp->Add(new Leaf("Leaf XA"));comp->Add(new Leaf("Leaf XB"));root->Add(comp);Composite *comp2 = new Composite("Composite XY");comp2->Add(new Leaf("Leaf XYA"));comp2->Add(new Leaf("Leaf XYB"));comp->Add(comp2);root->Add(new Leaf("Leaf C"));Leaf * leaf = new Leaf("Leaf D");root->Add(leaf);root->Remove(leaf);root->Display(1);return 0;
}

代码运行结果能显示出 树状的组件
在这里插入图片描述

透明方式和安全方式

透明方式
在这种实现里面 Component 中声明了所有用来管理子对象的方法 对于外界来说 叶子节点和子节点没有区别 它们具有完全一样的接口 Leaf 本身不具备Add Remove方法 所以实现它是没有任何意义的
安全方式
在Component里面不去声明Add 和 Remove方法 这样子类Left不需要去实现,而是在Composite声明所有用来管理子类对象的方法 这样做就不会遇到刚才遇到的问题 但是由于不够透明 所以树枝类将不具有相同的接口 客户端的调用需要做判断

应该视情况 来决定使用哪一种方式

什么时候使用组合模式

需求中体现部分和整体层次的结构的时候 希望用户可以忽略组合对象和单个对象的不同,统一地使用组合结构中的所有对象时 ,就应该考虑使用组合模式了
TreeView 控件使用的就是组合模式

公司管理系统使用 组合模式来构架

在这里插入图片描述


#include <iostream>
#include <list>
using namespace std;//组合中对象声明接口 实现所有类共有的默认接口行为
class Company {
public:Company(string name){this->name = name;}virtual void Add(Company *c) = 0;virtual void Remove(Company* c) = 0;virtual void Display(int depth) =0 ;//展示参数表示数的深度virtual void LineOfDuty() =0; //履行职责protected:string name;
};// 人力资源部门
class HRDepartment :public Company
{
public:HRDepartment(string name) :Company(name) {}void Add(Company* c) override {cout << "cannot add to a leaf " << endl;}void Remove(Company* c) override {cout << "cannot Remove from  a leaf " << endl;}void Display(int depth) override {string a = string(depth, '-');cout << a << name << endl;}void LineOfDuty()override{cout << name<<" 员工招聘培训管理 " << endl;}};//具体公司类 实现接口 树枝节点
class ConcreteCompany : public Company
{
public:ConcreteCompany(string name) :Company(name) {}void Add(Company *c) override {children.push_back(c);}void Remove(Company *c) override {children.remove(c);}void Display(int depth)override{cout << string(depth, '-') << name << endl;for (auto Com : children){Com->Display(depth + 2);}}//履行职责void LineOfDuty() override {for (auto Com : children){Com->LineOfDuty();}}private:list<Company*> children;
};//财务部
class FinanceDepartment :public Company
{
public:FinanceDepartment(string name) :Company(name) {}void Add(Company* c) override {cout << "cannot add to a leaf " << endl;}void Remove(Company* c) override {cout << "cannot Remove from  a leaf " << endl;}void Display(int depth) override {string a = string(depth, '-');cout << a << name << endl;}void LineOfDuty()override{cout << name << " 公司财务收支管理 " << endl;}};int main()
{ConcreteCompany * root = new ConcreteCompany("北京总公司");root->Add(new HRDepartment("总公司人力资源"));root->Add(new HRDepartment("总公司财务部门"));ConcreteCompany* comp = new ConcreteCompany("上海华东分公司");comp->Add(new HRDepartment("华东分公司人力资源部"));comp->Add(new HRDepartment("华东分公司财务部"));root->Add(comp);ConcreteCompany *comp2 = new ConcreteCompany("南京办事处");comp2->Add(new HRDepartment("南京办事处人力资源部"));comp2->Add(new HRDepartment("南京办事处财务部"));comp->Add(comp2);ConcreteCompany* comp1 = new ConcreteCompany("杭州办事处");comp1->Add(new HRDepartment("杭州办事处人力资源部"));comp1->Add(new HRDepartment("杭州办事处财务部"));comp->Add(comp1);cout << "结构图 :" << endl;root->Display(1);cout << "职责:" << endl;root->LineOfDuty();return 0;
}

运行后的结果图
在这里插入图片描述

组合模式的好处

组合模式定义基本对象和分公司 办事处结合对象的类层次结构 基本对象可以被组合成更复杂的类型
组合对象又可以被组合 这样不断地柜下去 客户代码 任何用到基本对象的地方都可以使用组合对象

组合模式让客户可以一致的使用组合结构和单个对象

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/317467.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

延时任务通知服务的设计及实现(二)-- redisson的延迟队列RDelayedQueue

一、接着上文 RDelayedQueue作为redisson封装的一个分布式延迟队列&#xff0c;直接拿来使用还是比较简单的。 本文主要包括以下几部分&#xff1a; 保存至延迟队列&#xff08;生产者&#xff09;读取延迟队列&#xff08;消费者&#xff09;从延迟队列移除任务 二、rediss…

el-form 表单设置某个参数非必填验证

html <el-form ref"form" :rules"rules"><el-form-item prop"tiktokEmail" label"邮箱" ><el-input v-model"form.tiktokEmail" placeholder"邮箱" ></el-input></el-form-item&…

原创度高!性能好!|基于信息共享与黄金搜索的改进星鸦优化算法在50+个函数上进行测试(Matlab)

文章来源于我的个人公众号&#xff1a;KAU的云实验台&#xff0c;主要更新智能优化算法的原理、应用、改进 前面的文章中&#xff0c;KAU介绍了星鸦优化算法(Nutcracker Optimization Algorithm&#xff0c;NOA)[1]&#xff0c;NOA算法模拟了星鸦觅食、存储以及缓存搜索、恢复…

人脸识别概念解析

目录 1. 概述 2. 人脸检测 3. 人脸跟踪 4. 质量评价 5. 活体检测 6. 特征提取 7. 人脸验证 8. 人脸辨识 1. 概述 人脸识别在我们的生活中随处可见&#xff0c;例如在大楼门禁系统中&#xff0c;它取代了传统的门禁卡或密码&#xff0c;提高了进出的便捷性和安全性。在商…

现代神经网络总结(AlexNet VGG GoogleNet ResNet的区别与改进)

VGG NIN GoogleNet 1.VGG&#xff0c;NIN&#xff0c;GoogleNet的块结构图对比(注意:无AlexNet) 这些块带来的区别与细节 AlexNet未使用块,主要对各个层进行了解: 卷积:捕捉特征 relu:增强非线性 池化层:减少计算量 norm:规范数据分布 全连接层:分类VGG块的改善(对比AlexNe…

理解Linux文件系统

文章目录 一、引言二、Linux文件系统概述1、文件系统的结构2、文件系统目录树的逻辑结构 二、文件系统的特性1、super block&#xff1a;文件系统的超级块2、inode&#xff1a;文件系统的索引节点3、inode table4、block&#xff1a;文件系统的数据块5、块组描述符表&#xff0…

Python 与 TensorFlow2 生成式 AI(二)

原文&#xff1a;zh.annas-archive.org/md5/d06d282ea0d9c23c57f0ce31225acf76 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第四章&#xff1a;教授网络生成数字 在前一章中&#xff0c;我们涵盖了神经网络模型的构建基块。在这一章中&#xff0c;我们的第一个项目…

CGAL 点云数据生成DSM、DTM、等高线和数据分类

原文链接 CGAL 点云数据生成DSM、DTM、等高线和数据分类 - 知乎 在GIS应用软件中使用的许多传感器(如激光雷达)都会产生密集的点云。这类应用软件通常利用更高级的数据结构&#xff1a;如&#xff1a;不规则三角格网 (TIN)是生成数字高程模型 (DEM) 的基础&#xff0c;也可以利…

【综述】多核处理器芯片

文章目录 前言 Infineon处理器 AURIX™系列 TC399XX-256F300S 典型应用 开发工具 参考资料 前言 见《【综述】DSP处理器芯片》 Infineon处理器 AURIX™系列&#xff0c;基于TriCore内核&#xff0c;用于汽车和工业领域。 XMC™系列&#xff0c;基于ARM Cortex-M内核&…

Power BI:如何将文件夹批量Excel(多sheet页)文件导入?

故事背景&#xff1a; 业务同事想用Power BI分析近两年市场费用。 数据源全部是Excel文件&#xff0c;并且以每月一个Excel文件的方式&#xff0c;统一存放到同一文件夹下面。 重点&#xff0c;每张Excel文件会有多张sheet页&#xff0c;用区分每家分公司的费用信息。 目前…

2023年蓝桥杯C++A组第三题:更小的数(双指针解法)

题目描述 小蓝有一个长度均为 n 且仅由数字字符 0 ∼ 9 组成的字符串&#xff0c;下标从 0 到 n − 1&#xff0c;你可以将其视作是一个具有 n 位的十进制数字 num&#xff0c;小蓝可以从 num 中选出一段连续的子串并将子串进行反转&#xff0c;最多反转一次。小蓝想要将选出的…

使用 Python 和 OpenCV 进行实时目标检测的详解

使用到的模型文件我已经上传了&#xff0c;但是不知道能否通过审核&#xff0c;无法通过审核的话&#xff0c;就只能 靠大家自己发挥实力了&#xff0c;^_^ 目录 简介 代码介绍 代码拆解讲解 1.首先&#xff0c;让我们导入需要用到的库&#xff1a; 2.然后&#xff0c;设…

ansible-playbook离线升级centos内核

目录 概述实践ansible目录结构关键代码执行效果 结束 概述 内核离线包官网下载地址如下&#xff1a; 地址 实践 ansible目录结构 如对 ansible 不熟悉&#xff0c;离线包下载有问题&#xff0c;请至此地址下载&#xff0c;按本文操作可直接使用。 相关文章链接如下 文章地…

水电气能耗管理云平台

安科瑞薛瑶瑶18701709087/17343930412 能耗管理云平台采用泛在物联、云计算、大数据、移动通讯、智能传感器等技术手段可为用户提供能源数据采集、统计分析、能效分析、用能预警、设备管理等服务&#xff0c;平台可以广泛应用于多种领域。

Centos的一些基础命令

CentOS是一个基于开源代码构建的免费Linux发行版&#xff0c;它由Red Hat Enterprise Linux (RHEL) 的源代码重新编译而成。由于 CentOS是基于RHEL构建的&#xff0c;因此它与RHEL具有非常类似的特性和功能&#xff0c;包括稳定性、安全性和可靠性。并且大部分的 Linux 命令在C…

基于H.264的RTP打包中的组合封包以及分片封包结构图简介及抓包分析;FU-A FU-B STAP-A STAP-B简介;

H.264视频流的RTP封装类型分析&#xff1a; 前言&#xff1a; 1.RTP打包原则&#xff1a; RTP的包长度必须要小于MTU(最大传输单元)&#xff0c;IP协议中MTU的最大长度为1500字节。除去IP报头&#xff08;20字节&#xff09;、UDP报头&#xff08;8字节&#xff09;、RTP头&a…

ZISUOJ 高级语言程序设计实训-基础C(部分题)

说明&#xff1a; 有几个题是不会讲的&#xff0c;我只能保证大家拿保底分。 题目列表&#xff1a; 问题 A: 求平均数1 思路&#xff1a; 送分题…… 参考题解&#xff1a; #include <iostream> #include <iomanip> using std::cin; using std::cout;int main(…

Django后台项目开发实战二

我们的需求是开发职位管理系统 三个功能&#xff1a; 管理员发布职位候选人能浏览职位用户能投递职位 第二阶段 创建应用 jobs&#xff0c;实现职位数据的建模 python manage.py startapp jobs 然后再 setting .py 注册应用&#xff0c;只需添加应用名称到最后一行 INST…

git 的迁移

现象是gitlab经常会挂掉&#xff0c;linux会显示磁盘空间不足&#xff0c;实际上&#xff0c;我们linux某个目录的空间是4T。这个空间应该是足够的。猜测是gitlab的安装目录不对导致的空间不足。 1、查找原因 用rpm 安装gitlab会有自己的目录&#xff0c;很多安装文件会在opt…

【华为】华为防火墙双机热备

【华为】华为防火墙双机热备 实验需求实验拓扑配置FW5-M前骤单臂路由和VRRP划分防火墙基本区域部署HRP&#xff08;华为心跳协议&#xff09; FW6-B前骤单臂路由和VRRP划分防火墙基本区域部署HRP&#xff08;华为心跳协议&#xff09; LSW2PC NATSNAT &#xff1a;Easy IPDNAT&…