当前位置: 首页 > java >正文

5.组合模式

目录

  • 一、概念
  • 二、类图详解
  • 三、组合模式实现步骤
  • 四、代码实现
    • 4.1 Component类
    • 4.2 Composite类
    • 4.3 Leaf类
    • 4.4 测试
  • 五、扩展

一、概念

  • 组合模式又叫整体--部分模式
  • 组合模式描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它们进行区分
  • 可以一致地对待容器对象和叶子对象。
  • 它使树型结构的问题中,模糊了简单元素复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

二、类图详解

在这里插入图片描述

  • 包含一个抽象组件类Component、叶子结点类Leaf和组件集合类Composite
  • 抽象组件类:组合中的对象声明接口,实现所有类共有接口的行为。声明用于访问和管理Component的子部件的接口。
  • 叶子结点:叶节点对象,就是终端独立结点,不能addRemove其它组件。
  • 组件集合类:实现Component的相关操作,可以继续包含组件集合类和叶子结点。
  • CompositeComponent类形成迭代关联关系。

三、组合模式实现步骤

  • 定义抽象组件接口
  • 实现叶子节点类,实现抽象组件类的接口。
  • 实现组件集合类,实现抽象组件类的接口。
  • 定义环境类,将叶子节点和组件集合加入根组件集合。

四、代码实现

  • 生成目录树结构,目录里面可以再放目录或文件
  • 最终的输出如下
    在这里插入图片描述

4.1 Component类

  • 顶层接口
#pragma once
#include <iostream>class Component
{
public:std::string name;  //叶子结点和组件结点都有名字和类型bool m_isLeaf;     //是否是叶子结点(暂时没用)Component(const std::string& name, bool isLeaf){this->name = name;this->m_isLeaf = isLeaf;}virtual void Add(Component* c) = 0;virtual void Remove(Component* c) = 0;virtual void Display(int depth) = 0;bool isLeaf() const{return this->m_isLeaf;}
};

4.2 Composite类

  • 用来放文件夹或文件
#pragma once
#include <iostream>
#include <list>#include "Component.h"class Composite: public Component
{
private:std::list<Component*> m_component;public:Composite(const std::string& name) : Component(name, false){}void Add(Component* c) override{m_component.push_back(c);}void Remove(Component* c) override{m_component.remove(c);}void Display(int depth) override{std::cout << std::string(depth, '-') << name << std::endl;for (auto item : m_component){item->Display(depth + 2);}}
};

4.3 Leaf类

  • 用来放文件
#pragma once
#include <iostream>
#include "Component.h"class Leaf: public Component
{
public:Leaf(const std::string& name): Component(name, true){}void Add(Component* c) override{std::cout << "Can't add component to leaf." << std::endl;}void Remove(Component* c) override{std::cout << "Can't remove component to leaf." << std::endl;}void Display(int depth) override{std::cout << std::string(depth, '-') << name << std::endl;}
};

4.4 测试

#include "Leaf.h"
#include "Composite.h"class Client
{
private:Component* com;public:Client(Component* obj){com = obj;}void display(int n){com->Display(n);}
};int main()
{Component* root = new Composite("根目录");root->Add(new Leaf("根目录下的文件A"));root->Add(new Leaf("根目录下的文件B"));Component* dir1 = new Composite("根目录下的文件夹FA");dir1->Add(new Leaf("文件夹FA下的文件A"));dir1->Add(new Leaf("文件夹FA下的文件B"));root->Add(dir1);Component* dir2 = new Composite("根目录FA下的文件夹FAX");dir2->Add(new Leaf("文件夹FAX下的文件A"));dir2->Add(new Leaf("文件夹FAX下的文件B"));dir1->Add(dir2);root->Add(new Leaf("根目录下的文件C"));root->Add(new Leaf("根目录下的文件D"));Client c(root);c.display(1);return 0;
}

五、扩展

  • 设计一个饭店的菜单
  • 可以再包含一个菜单或者菜单项
  • 类图如下
    在这里插入图片描述
  • 菜单项图结构如下
    在这里插入图片描述
  • 代码部分请参阅 https://gitee.com/piglittle/design_patterns中的 Head_First_Design_Partterns解决方案下的 composite_pattern项目
http://www.xdnf.cn/news/15731.html

相关文章:

  • Node.js net.Socket.destroy()深入解析
  • 4.循环结构:让电脑做重复的事情
  • 探秘边缘安全架构设计要点解析
  • Redis 如何保证高并发与高可用
  • 【计算机网络架构】树型架构简介
  • 车载传统ECU---MCU软件架构设计指南
  • Netty网络聊天室及扩展序列化算法
  • 2025年睿抗机器人开发者大赛CAIP-编程技能赛(省赛)-RoboCom 世界机器人开发者大赛-本科组
  • FreeRTOS学习笔记之软件定时器
  • 【初识数据结构】CS61B中的基本图算法:DFS, BFS, Dijkstra, A* 算法及其来历用法
  • Java-77 深入浅出 RPC Dubbo 负载均衡全解析:策略、配置与自定义实现实战
  • CS231n-2017 Lecture3线性分类器笔记
  • 时序数据库选型实战:Apache IoTDB技术深度解析
  • 用逻辑回归(Logistic Regression)处理鸢尾花(iris)数据集
  • 移除debian升级后没用的垃圾
  • 电商商品综合排序:从需求分析到实时计算的全方位指南
  • 鸿蒙与web混合开发双向通信
  • The Missing Semester of Your CS Education 学习笔记以及一些拓展知识(三)
  • HTTP性能优化实战
  • Matplotlib和Plotly知识点(Dash+Plotly分页展示)
  • Android 开发实战:从零到一集成 espeak-ng 实现中文离线 TTS(无需账号开箱即用)
  • Qt笔记整理(1)
  • CCF编程能力等级认证GESP—C++5级—20250628
  • 使用nvm安装node、npm、pnpm以及编译项目教程
  • SpringBoot 3.0 挥别 spring.factories,拥抱云原生新纪元
  • 基于大模型打造故障预警服务器巡检机器人
  • Jetpack Compose中的Modifier:UI元素的装饰与行为扩展
  • 3-大语言模型—理论基础:生成式预训练语言模型GPT(代码“活起来”)
  • [论文阅读] 软件工程 | 用模糊逻辑“解锁”项目成功:告别非黑即白的评估时代
  • 网络基础DAY13-NAT技术