重温设计模式--组合模式

文章目录

  • 1 、组合模式(Composite Pattern)概述
  • 2. 组合模式的结构
  • 3. C++ 代码示例
  • 4. C++示例代码2
  • 5 .应用场景

1 、组合模式(Composite Pattern)概述

  • 定义:组合模式是一种结构型设计模式,它允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
  • 作用
    • 简化客户端代码:客户端可以统一地处理单个对象和对象组合,而不需要区分它们是单个的叶子节点还是包含多个子节点的组合节点。例如,在一个文件系统的表示中,客户端可以用相同的方式来处理文件(叶子节点)和文件夹(组合节点),如计算文件大小或显示文件/文件夹名称等操作。
    • 层次结构表示:能够很好地表示具有层次结构的对象关系。比如公司的组织结构,一个部门(组合节点)可以包含多个子部门和员工(叶子节点),通过组合模式可以清晰地构建和遍历这种层次结构。
    • 灵活的对象组合:可以方便地添加新的叶子节点或组合节点,构建出复杂的对象树,并且可以动态地修改这个树的结构,而不影响客户端对树的整体操作。
      在这里插入图片描述

2. 组合模式的结构

  • 组件(Component):这是组合模式中的抽象类或接口,它为组合中的对象(包括叶子节点和组合节点)定义了统一的接口,如操作方法、添加子节点方法(对于组合节点)、删除子节点方法(对于组合节点)等。
  • 叶子(Leaf):叶子节点是组合中的最底层对象,它没有子节点,实现了组件接口定义的方法,但不包含添加或删除子节点相关的操作,因为它本身不能再包含其他对象。
  • 组合(Composite):组合节点代表了包含子节点的对象,它实现了组件接口,并且内部维护了一个子节点列表。它的方法实现通常是遍历子节点列表,调用子节点的相应方法来完成操作,同时也实现添加和删除子节点的方法来管理子节点列表。

3. C++ 代码示例

  • 以下以一个简单的图形绘制系统为例,图形可以是简单的基本图形(如圆形、矩形,相当于叶子节点),也可以是由多个图形组成的复杂图形(相当于组合节点)。
#include <iostream>
#include <vector>

// 组件抽象类
class Graphic
{
public:
	virtual void draw() = 0;
	virtual ~Graphic() {}
};

// 叶子节点:圆形
class Circle : public Graphic
{
public:
	void draw()
	{
		std::cout << "绘制圆形" << std::endl;
	}
};

// 叶子节点:矩形
class Rectangle : public Graphic 
{
public:
	void draw()
	{
		std::cout << "绘制矩形" << std::endl;
	}
};

// 组合节点:复杂图形
class ComplexGraphic : public Graphic
{
private:
	std::vector<Graphic*> graphics;
public:
	void draw()
	{
		for (std::vector<Graphic*>::iterator it = graphics.begin(); it!= graphics.end(); ++it)
		{
			(*it)->draw();
		}
	}
	void add(Graphic* graphic)
	{
		graphics.push_back(graphic);
	}
	void remove(Graphic* graphic)
	{
		for (std::vector<Graphic*>::iterator it = graphics.begin(); it!= graphics.end(); ++it)
		{
			if (*it == graphic)
			{
				graphics.erase(it);
				break;
			}
		}
	}
	~ComplexGraphic()
	{
		graphics.clear();
	}
};

int main() 
{
	// 创建叶子节点图形
	Circle circle;
	Rectangle rectangle;
	// 创建组合节点图形并添加叶子节点图形
	ComplexGraphic complexGraphic;
	complexGraphic.add(&circle);
	complexGraphic.add(&rectangle);
	// 绘制组合图形,会依次绘制组合中的所有图形
	complexGraphic.draw();
	return 0;
}

在上述代码中:

  • Graphic是组件抽象类,定义了draw方法作为统一的接口,用于绘制图形。
  • CircleRectangle是叶子节点类,它们分别实现了draw方法来绘制具体的基本图形。
  • ComplexGraphic是组合节点类,内部维护了一个Graphic指针的向量来存储子图形。draw方法通过遍历子图形向量并调用每个子图形的draw方法来绘制整个复杂图形,addremove方法用于管理子图形列表。在main函数中,首先创建了基本图形对象,然后创建了复杂图形对象并添加基本图形对象到其中,最后通过调用复杂图形对象的draw方法来绘制整个组合图形,展示了组合模式在图形绘制系统中的简单应用。

4. C++示例代码2

#include<iostream>
#include<list>
#include<string>
using namespace std;
//将对象组合成树形结构以表示“部分-整体”的层次结构。
//组合模式使得用户对单个对象和组合对象的使用具有一致性

class Company
{
public:
	Company(string name) { m_name = name; }
	virtual ~Company(){}
	virtual void Add(Company *pCom){}
	virtual void Show(int depth) {}
protected:
	string m_name;
};
//具体公司
class ConcreteCompany : public Company
{
public:
	ConcreteCompany(string name): Company(name) {}
	virtual ~ConcreteCompany() {}
	void Add(Company *pCom) { m_listCompany.push_back(pCom); } //位于树的中间,可以增加子树
	void Show(int depth)
	{
		for(int i = 0;i < depth; i++)
		{
			cout<<"-";
		}
		cout<<m_name<<endl;
		list<Company *>::iterator iter=m_listCompany.begin();
		for(; iter != m_listCompany.end(); iter++) //显示下层结点
		{
			(*iter)->Show(depth + 2);
		}
	}
private:
	list<Company *> m_listCompany;
};
//具体的部门,财务部
class FinanceDepartment : public Company
{
public:
	FinanceDepartment(string name):Company(name){}
	virtual ~FinanceDepartment() {}
	virtual void Show(int depth) //只需显示,无限添加函数,因为已是叶结点
	{
		for(int i = 0; i < depth; i++)
		{
			cout<<"-";
		}
		cout<<m_name<<endl;
	}
};
//具体的部门,人力资源部
class HRDepartment :public Company
{
public:
	HRDepartment(string name):Company(name){}
	virtual ~HRDepartment() {}
	virtual void Show(int depth) //只需显示,无限添加函数,因为已是叶结点
	{
		for(int i = 0; i < depth; i++)
		{
			cout<<"-";
		}
		cout<<m_name<<endl;
	}
};

int main()
{
	Company *root = new ConcreteCompany("总公司");
	Company *leaf1=new FinanceDepartment("财务部");
	Company *leaf2=new HRDepartment("人力资源部");
	root->Add(leaf1);
	root->Add(leaf2);

	//分公司A
	Company *mid1 = new ConcreteCompany("分公司A");
	Company *leaf3=new FinanceDepartment("财务部");
	Company *leaf4=new HRDepartment("人力资源部");
	mid1->Add(leaf3);
	mid1->Add(leaf4);
	root->Add(mid1);
	//分公司B
	Company *mid2=new ConcreteCompany("分公司B");
	FinanceDepartment *leaf5=new FinanceDepartment("财务部");
	HRDepartment *leaf6=new HRDepartment("人力资源部");
	mid2->Add(leaf5);
	mid2->Add(leaf6);
	root->Add(mid2);
	root->Show(0);

	delete leaf1; delete leaf2;
	delete leaf3; delete leaf4;
	delete leaf5; delete leaf6;
	delete mid1; delete mid2;
	delete root;
	return 0;
}

输出:
总公司
--财务部
--人力资源部
--分公司A
----财务部
----人力资源部
--分公司B
----财务部
----人力资源部
请按任意键继续. . .



组合模式让客户一致的使用组合结构和单个对象,他们的接口是统一透明的,这样用户就无须做判断,然后根据不同的结果去执行不同的动作了。

5 .应用场景

  1. 文件系统和目录结构表示
    • 描述层次关系:文件系统是典型的树形层次结构,由文件(叶子节点)和文件夹(组合节点)组成。组合模式可以很好地对其进行建模。例如,在操作系统的文件管理器中,每个文件夹可以包含文件和子文件夹,使用组合模式可以用统一的方式处理文件和文件夹的操作,如计算文件夹大小(需要递归计算子文件夹和文件的大小)、显示文件和文件夹列表、复制或移动文件夹(包括其内部的所有文件和子文件夹)等操作。
    • 权限管理:对于文件系统的访问权限设置,权限可以从文件夹继承到文件。通过组合模式,可以方便地为文件夹(组合节点)设置权限,并将这些权限传播给其包含的文件(叶子节点)和子文件夹,确保整个文件系统层次结构的权限一致性。
  2. 图形用户界面(GUI)组件层次结构
    • 构建界面布局:在GUI设计中,窗口、面板(如容器面板)是组合节点,而按钮、文本框等是叶子节点。组合模式用于构建复杂的用户界面布局。例如,一个窗口可以包含多个面板,每个面板又可以包含按钮、文本框等各种控件。通过组合模式,可以方便地添加、删除或重新排列这些界面组件,并且可以对整个界面或部分组件进行统一的操作,如显示、隐藏、设置样式等。
    • 事件处理和消息传递:在GUI系统中,事件(如鼠标点击、键盘输入)需要在组件层次结构中传播。组合模式可以帮助实现事件从顶层窗口向下传递到具体的叶子节点组件,或者从底层组件向上冒泡到父容器组件,从而实现合理的事件处理机制。
  3. 组织结构和资源管理
    • 企业组织结构建模:企业的组织结构是一个层次分明的体系,包括部门(组合节点)和员工(叶子节点)。组合模式可以用于表示这种组织结构,方便进行资源分配、任务分配等操作。例如,人力资源部门可以通过组合模式表示的组织结构,为整个公司(根节点)或者某个部门(子组合节点)统一进行工资核算、培训安排等操作,这些操作可以递归地应用到部门内的所有员工(叶子节点)。
    • 计算机集群资源管理:在计算机集群环境中,集群(组合节点)由多个计算节点(叶子节点)组成。通过组合模式,可以对集群资源进行统一管理,如分配任务到集群(将任务分配到具体的计算节点)、监控集群状态(包括各个计算节点的状态)、进行软件安装和更新(在集群范围内或者部分计算节点范围内)等操作。
  4. 游戏开发中的场景和对象管理
    • 游戏场景构建:游戏场景通常包含各种游戏对象,如角色(叶子节点)、道具(叶子节点)和地形(组合节点,可能包含多个子地形区域)等。组合模式可以用于构建游戏场景,方便游戏开发者添加、删除或修改游戏场景中的对象。例如,在一个角色扮演游戏中,可以通过组合模式创建一个包含多个区域(组合节点)的大地图场景,每个区域又包含角色、道具等对象,对整个场景或者部分区域的操作(如渲染、碰撞检测等)可以通过组合模式统一进行。
    • 游戏对象层次关系处理:游戏中的一些对象可能具有父子关系,如角色装备(叶子节点)与角色本身(组合节点)。通过组合模式,可以更好地处理这种对象层次关系,例如,当角色移动时,其装备也随之移动;当角色受到攻击时,其装备的属性(如防御值)可以对攻击进行响应,这种对象之间的关联和操作可以通过组合模式来清晰地实现。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

漏洞检测工具:Swagger UI敏感信息泄露

Swagger UI敏感信息泄露 漏洞定义 Swagger UI是一个交互式的、可视化的RESTful API文档工具&#xff0c;它允许开发人员快速浏览、测试API接口。Swagger UI通过读取由Swagger&#xff08;也称为OpenAPI&#xff09;规范定义的API描述文件&#xff08;如swagger.json或swagger…

Linux下学【MySQL】表中插入和查询的进阶操作(配实操图和SQL语句通俗易懂)

绪论​ 每日激励&#xff1a;挫折是会让我们变得越来越强大的重点是我们敢于积极的面对它。—Jack叔叔 绪论​&#xff1a; 本章是表操作的进阶篇章&#xff08;没看过入门的这里是传送门&#xff0c;本章将带你进阶的去学习表的插入insert和查找select&#xff0c;本质也就是…

JavaScript 标准内置对象——Object

1、构造函数 2、静态方法 // 将源对象中所有可枚举的自有属性复制到目标对象&#xff0c;&#xff0c;并返回修改后的目标对象 Object.assign(target, ...sources) Object.create(proto, propertiesObject) // 以一个现有对象作为原型&#xff0c;创建一个新对象Object.defineP…

Robot Framework搭建自动化测试框架

1.配置环境 需要安装jdk8&#xff0c;andrid sdk&#xff08;安装adb&#xff09;&#xff0c;pycharm编译环境以及软件 安装Robot Framework 首先&#xff0c;你需要安装Robot Framework&#xff0c;可以使用 pip 进行安装&#xff1a; pip install robotframework安装所需的…

fastjson诡异报错

1、环境以及报错描述 1.1 环境 操作系统为中标麒麟、cpu 为国产鲲鹏服务器。 jdk为openjdk version 1.8.0._242 1.2 错误 com.alibaba.fastjson2.JSONException: syntax error : f at com.alibaba.fastjson2.JSONReaderUTF16.readBoolValue(JSONReaderUTF16.java:6424) at c…

Unity3d 基于UGUI和VideoPlayer 实现一个多功能视频播放器功能(含源码)

前言 随着Unity3d引擎在数字沙盘、智慧工厂、数字孪生等场景的广泛应用&#xff0c;视频已成为系统程序中展示时&#xff0c;不可或缺的一部分。在 Unity3d 中&#xff0c;我们可以通过强大的 VideoPlayer 组件和灵活的 UGUI 系统&#xff0c;将视频播放功能无缝集成到用户界面…

蓝牙协议——音乐启停控制

手机播放音乐 手机暂停音乐 耳机播放音乐 耳机暂停音乐

【EthIf-13】EthIfGeneral容器配置-01

1.EthIfGeneral类图结构 下面是EthIfGeneral配置参数的类图&#xff0c;比较重要的参数就是配置&#xff1a; 接收中断是否打开发送确认中断是否打开EthIf轮询周期 1.EthIfGeneral参数的含义

如何看待2024年诺贝尔物理学奖颁给了机器学习与神经网络?

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于2024年诺贝尔物理学奖颁给了机器学习与神…

有没有检测吸烟的软件 ai视频检测分析厂区抽烟报警#Python

在现代厂区管理中&#xff0c;安全与规范是重中之重&#xff0c;而吸烟行为的管控则是其中关键一环。传统的禁烟管理方式往往依赖人工巡逻&#xff0c;效率低且存在监管死角&#xff0c;难以满足当下复杂多变的厂区环境需求。此时&#xff0c;AI视频检测技术应运而生&#xff0…

VSCode搭建Java开发环境 2024保姆级安装教程(Java环境搭建+VSCode安装+运行测试+背景图设置)

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。—— 苏轼《水调歌头》 创作者&#xff1a;Code_流苏(CSDN) 目录 一、Java开发环境搭建二、VScode下载及安装三、VSCode配置Java环境四、运行测试五、背景图设置 很高兴你打开了这篇博客&#xff0c;更多详细的安装教程&…

二手车交易平台开发:安全与效率的双重挑战

3.1系统体系结构 系统的体系结构非常重要&#xff0c;往往决定了系统的质量和生命周期。针对不同的系统可以采用不同的系统体系结构。本系统为二手车交易平台系统&#xff0c;属于开放式的平台&#xff0c;所以在体系结构中采用B/s。B/s结构抛弃了固定客户端要求&#xff0c;采…

共享无人系统,从出行到生活全面覆盖

共享无人系统已经覆盖到我们生活中的方方面面&#xff0c;出行上&#xff0c;比如共享自行车小程序、共享自行车&#xff1b;生活中&#xff0c;比如说棋牌室、茶室。我们以棋牌室举例。 通过开发使用共享无人系统&#xff0c;可以极大地降低人力成本&#xff0c;共享无人棋牌室…

FPGA学习(基于小梅哥Xilinx FPGA)学习笔记

文章目录 一、整个工程的流程二、基于Vivado的FPGA开发流程实践&#xff08;二选一多路器&#xff09;什么是二选一多路器用verilog语言&#xff0c;Vivado软件进行该电路实现1、设计输入&#xff1a;Design Sources中的代码2、分析和综合&#xff1a;分析设计输入中是否有错误…

四相机设计实现全向视觉感知的开源空中机器人无人机

开源空中机器人 基于深度学习的OmniNxt全向视觉算法OAK-4p-New 全景硬件同步相机 机器人的纯视觉避障定位建图一直是个难题&#xff1a; 系统实现复杂 纯视觉稳定性不高 很难选到实用的视觉传感器 为此多数厂家还是采用激光雷达的定位方案。 OAK-4p-New 为了弥合这一差距…

突破续航瓶颈:数字样机技术引领新能源汽车复合制动新方向

随着我国经济快速发展和人民生活水平不断提升&#xff0c;汽车保有量截至2023年9月底就已达到了3.3亿&#xff0c;同比增长6.32%。庞大的汽车保有量对我国的环境和能源都产生了巨大的压力&#xff0c;具备节能环保优势的新能源汽车对于有效解决环境恶化和能源危机问题具有重要意…

基于股票日频 K 线的自动因子挖掘实践

遗传算法最初由美国密歇根大学的 J.Holland 提出&#xff0c;是一种通过模拟自然界生物进化的过程来搜索最优解的算法&#xff0c;应用于量子计算、电子设计、游戏比赛等多种场景。 以大家熟知的 python gplearn 为例&#xff0c;它就是一款基于遗传算法开发的数据分析工具&am…

考前96天 学习巩固 计算机、数学、英语

2024年12月24日到2025年3月29日共有 96​ 天 一、计算机基础 回顾&#xff1a; 三大思维&#xff1a; 数学 推理/理论 物理 证实/实验 计算机 构造/计算 本质——》抽象/自动化 计算复杂性&#xff1a;空间复杂性、时间复杂性 计算机系统的组成&#xff1a; 1️⃣硬件…

Artec Space Spider助力剑桥研究团队解码古代社会合作【沪敖3D】

挑战&#xff1a;考古学家需要一种安全的方法来呈现新出土的陶瓷容器&#xff0c;对比文物形状。 解决方案&#xff1a;Artec Space Spider, Artec Studio 效果&#xff1a;本项目是REVERSEACTION项目的一部分&#xff0c;旨在研究无国家社会中复杂的古代技术。研究团队在考古地…

云原生服务网格Istio实战

基础介绍 1、Istio的定义 Istio 是一个开源服务网格&#xff0c;它透明地分层到现有的分布式应用程序上。 Istio 强大的特性提供了一种统一和更有效的方式来保护、连接和监视服务。 Istio 是实现负载平衡、服务到服务身份验证和监视的路径——只需要很少或不需要更改服务代码…