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

ops/2024/12/25 3:16:27/

文章目录

  • 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);//分公司ACompany *mid1 = new ConcreteCompany("分公司A");Company *leaf3=new FinanceDepartment("财务部");Company *leaf4=new HRDepartment("人力资源部");mid1->Add(leaf3);mid1->Add(leaf4);root->Add(mid1);//分公司BCompany *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. 游戏开发中的场景和对象管理
    • 游戏场景构建:游戏场景通常包含各种游戏对象,如角色(叶子节点)、道具(叶子节点)和地形(组合节点,可能包含多个子地形区域)等。组合模式可以用于构建游戏场景,方便游戏开发者添加、删除或修改游戏场景中的对象。例如,在一个角色扮演游戏中,可以通过组合模式创建一个包含多个区域(组合节点)的大地图场景,每个区域又包含角色、道具等对象,对整个场景或者部分区域的操作(如渲染、碰撞检测等)可以通过组合模式统一进行。
    • 游戏对象层次关系处理:游戏中的一些对象可能具有父子关系,如角色装备(叶子节点)与角色本身(组合节点)。通过组合模式,可以更好地处理这种对象层次关系,例如,当角色移动时,其装备也随之移动;当角色受到攻击时,其装备的属性(如防御值)可以对攻击进行响应,这种对象之间的关联和操作可以通过组合模式来清晰地实现。

http://www.ppmy.cn/ops/144735.html

相关文章

mysql 查询优化之字段建立全文索引

最近在接手一些老项目时发现表设计存在问题导致查询较慢 例如一张旧表的设计&#xff1a; 模糊匹配某个关键字时,需要十几秒左右,而且表的数据量不多 都知道mysql8.0版本InnoDB引擎都支持全文索引了,因此可以在content建立全文索引&#xff0c;但全文索引对中文支持并不完善…

设计模式--工厂方法模式【创建型模式】

设计模式的分类 我们都知道有 23 种设计模式&#xff0c;这 23 种设计模式可分为如下三类&#xff1a; 创建型模式&#xff08;5 种&#xff09;&#xff1a;单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。结构型模式&#xff08;7 种&#xff09;&#xff1…

Windows下ESP32-IDF开发环境搭建

Windows下ESP32-IDF开发环境搭建 文章目录 Windows下ESP32-IDF开发环境搭建一、软件安装二、搭建IDF开发环境2.1 安装VS Code插件&#xff1a;2.2 配置ESP-IDF插件&#xff1a;2.3 下载例程源码&#xff1a; 三、编译和烧录代码四、Windows下使用命令行编译和烧录程序4.1 配置环…

Docker安装

目录 1. 联网安装 Docker 2. 离线安装 Docker 3. 安装 Docker Compose 4. 卸载 Docker 和 Docker Compose 1. 联网安装 Docker 在 CentOS 上通过 yum 安装 Docker&#xff1a; # 安装 Docker yum -y install docker # 启动 Docker systemctl start docker # 查看 D…

2024-12-24 NO1. XR Interaction ToolKit 环境配置

文章目录 1 软件配置2 安装 XRToolKit3 配置 OpenXR4 安装示例场景5 运行测试 1 软件配置 Unity 版本&#xff1a;Unity6000.0.26 ​ 2 安装 XRToolKit 创建新项目&#xff08;URP 3D&#xff09;&#xff0c;点击进入 Asset Store。 进入“Unity Registry”页签&#xff0…

通过Hydra 配置文件实例化Lightning类

通过 Hydra 的配置文件灵活控制 LightningModule、LightningDataModule、Callback 和 Trainer 的实例化过程。 Lightning 与 Hydra 的结合 1. 配置文件结构 一个典型的配置文件目录可能如下: configs/ ├── callbacks/ │ ├── early_stopping.yaml │ ├── che…

亚远景-SO 21434标准下的汽车网络安全:风险评估与管理的关键实践

ISO 21434标准&#xff0c;全称为ISO/SAE 21434 "Road Vehicles - Cybersecurity Engineering"&#xff0c;是国际标准化组织(ISO)发布的针对汽车领域的标准&#xff0c;旨在指导汽车制造商、供应商和相关利益相关方在汽车系统中应用适当的网络安全措施。在ISO 21434…

云手机有哪些用途?云手机选择推荐

云手机的使用范围日益扩大&#xff0c;无论是个人使用&#xff0c;还是各种规模的中小型工作室需要进行养号、挂机、参加活动甚至完成各种测试需求&#xff0c;都已经开始大量采用云手机。以前&#xff0c;许多公司或工作室都自行建设手机批量控制的设备&#xff0c;但需要自行…