设计模式-结构型-组合模式

1. 什么是组合模式?

组合模式(Composite Pattern) 是一种结构型设计模式,它允许将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得客户端对单个对象和组合对象的使用具有一致性。换句话说,组合模式允许你将多个对象组合成一个复合对象,然后统一处理这些对象

核心思想

组合模式通过将简单对象(叶子节点)和复合对象(包含子对象的树形结构)统一视为相同的类型,从而简化客户端对不同类型对象的处理。它常用于表示树形结构,如目录结构、组织架构等。


2. 组合模式的结构

UML 类图

以下是组合模式的 UML 类图:

角色

  1. Component(抽象组件)
    定义了所有对象(无论是叶子节点还是组合节点)共用的方法,如 operation()。可以是抽象类或接口。

  2. Leaf(叶子节点)
    叶子节点是组合树结构的最底层元素,不能再包含子对象。它实现了 operation() 方法,通常用于具体的操作。

  3. Composite(组合节点)
    组合节点包含叶子节点或其他组合节点。它也实现了 operation() 方法,并允许对子节点进行操作(如 add()remove() 等)。通常用来组织和管理子组件。


3. 组合模式的示例

场景描述

假设我们需要构建一个文件系统的树形结构,其中包含文件夹(可以包含文件和子文件夹)和文件。文件和文件夹都有一个 display() 方法。组合模式可以帮助我们统一处理文件和文件夹。

代码实现

from abc import ABC, abstractmethod# 抽象组件类
class FileSystemComponent(ABC):@abstractmethoddef display(self):pass# 叶子节点:文件类
class File(FileSystemComponent):def __init__(self, name):self.name = namedef display(self):print(f"File: {self.name}")# 组合节点:文件夹类
class Folder(FileSystemComponent):def __init__(self, name):self.name = nameself.children = []def add(self, component: FileSystemComponent):self.children.append(component)def remove(self, component: FileSystemComponent):self.children.remove(component)def display(self):print(f"Folder: {self.name}")for child in self.children:child.display()# 测试组合模式
if __name__ == "__main__":# 创建文件和文件夹file1 = File("file1.txt")file2 = File("file2.txt")file3 = File("file3.txt")folder1 = Folder("Folder1")folder2 = Folder("Folder2")folder1.add(file1)folder1.add(file2)folder2.add(file3)# 创建根文件夹,添加子文件夹root = Folder("Root")root.add(folder1)root.add(folder2)# 显示整个文件系统结构root.display()

输出

Folder: Root

Folder: Folder1

File: file1.txt

File: file2.txt

Folder: Folder2

File: file3.txt

在上面的代码中,FileSystemComponent 是抽象组件类,File 是叶子节点,Folder 是组合节点。Folder 具有 add()remove() 方法来管理其子节点,而 File 只有 display() 方法。最后,通过调用根文件夹的 display() 方法,能够递归地显示整个文件系统的结构。


4. 组合模式的优缺点

优点

  1. 简化客户端代码
    客户端不需要关心对象是单个对象还是组合对象,它们可以通过相同的接口进行处理,简化了代码结构。

  2. 递归结构清晰
    组合模式特别适合处理递归结构的数据,比如文件系统、组织结构等。

  3. 增加或删除元素方便
    通过组合模式,添加或删除树形结构中的节点(文件或文件夹)非常方便,不影响其它节点的操作。

  4. 高扩展性
    可以轻松扩展新的叶子节点或组合节点,而不需要修改现有的客户端代码。

缺点

  1. 复杂性增加
    如果对象结构本身并不复杂,引入组合模式可能会让系统变得过于复杂,导致不必要的开销。

  2. 不易实现对叶子节点的具体行为
    在某些情况下,叶子节点的行为可能与组合节点有所不同,这可能会导致设计上的矛盾,难以通过统一接口来处理。


5. 组合模式的应用场景

  1. 文件系统
    文件夹可以包含子文件夹和文件,文件和文件夹是不同的对象类型,但是它们都实现了一个公共接口 display(),可以统一处理。

  2. GUI 组件库
    许多图形用户界面组件(如按钮、窗体、标签等)可以通过组合模式来处理。组件(如按钮)可以是叶子节点,而容器(如面板、窗体)可以是组合节点。

  3. 组织架构
    企业的组织架构可以通过组合模式表示。一个部门可以包含多个员工或者子部门,所有部门和员工都可以通过统一的接口进行管理。

  4. 树形结构的表示
    任何需要树形结构表示的场景,例如目录树、家族谱、层次化数据展示等,都适合使用组合模式。


6. 总结

组合模式 是一种非常强大的结构型设计模式,它能够有效地处理树形结构的数据,同时使得客户端代码对单一对象和组合对象的处理保持一致性。通过组合模式,您可以更轻松地管理复杂的对象结构,并且增加或删除节点时不会影响到其他部分。

核心要点

  1. 统一对待单一对象与组合对象
  2. 递归结构使得复杂对象的管理变得简单
  3. 组合模式简化客户端代码,使其更加灵活

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

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

相关文章

HQChart使用教程30-K线图如何对接第3方数据44-DRAWPIE数据结构

HQChart使用教程30-K线图如何对接第3方数据44-DRAWPIE数据结构 效果图DRAWPIEHQChart代码地址后台数据对接说明示例数据数据结构说明效果图 DRAWPIE DRAWPIE是hqchart插件独有的绘制饼图函数,可以通过麦语法脚本来绘制一个简单的饼图数据。 饼图显示的位置固定在右上角。 下…

Proser:升级为简易的通讯调试助手软件

我本来打算将Proser定位为一个直观的协议编辑、发送端模拟软件,像下面这样。 但是按耐不住升级的心理,硬生生的把即时收发整合了进去,就像这样! 不过,目前针对即时收发还没有发送历史、批量发送等功能,…

PyTorch环境配置常见报错的解决办法

目标 小白在最基础的环境配置里一般都会出现许多问题。 这里把一些常见的问题分享出来。希望可以节省大家一些时间。 最终目标是可以在cmd虚拟环境里进入jupyter notebook,new的时候有对应的环境,并且可以跑通所有的import code。 第一步:…

【Linux系列】Curl 参数详解与实践应用

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Web基础-分层解耦

思考:什么是耦合?什么是内聚?软件设计原则是什么? 耦合:衡量软件中各个层 / 各个模块的依赖关联程度。 内聚:软件中各个功能模块内部的功能联系。 软件设计原则:高内聚低耦合。 那我们该如何实现…

算法题(33):长度最小的子数组

审题: 需要我们找到满足元素之和大于等于target的最小子数组的元素个数,并返回 思路: 核心:子数组共有n种起点,nums数组的每个元素都可以充当子数组的首元素,我们只需要先确定子数组的首元素,然后往后查找满…

网络数据通信基本流程

1.基本概念 网络通信就是发送数据、接收数据、处理数据的过程,发送数据时要读数据进行处理(封装),接收数据时也要对数据进行处理(分用), 1)封装 对数据进行加工处理,如…

科创驱动 | 华望系统科技荣膺西湖区年度前沿创新新锐企业

2025年1月3日,由中共西湖区党委、西湖区人民政府主办的“新年第一会”—西湖区科技创新大会在杭州隆重举行。大会现场揭晓了西湖区年度科技创新团队与项目,并发布了“2024西湖区科技十大事件”与“西湖区五大年度科技榜单”。杭州华望系统科技有限公司榜…

Java Web开发基础:HTML的深度解析与应用

文章目录 前言🌍一.B/S 软件开发架构简述🌍二.HTML 介绍❄️2.1 官方文档❄️2.2 网页的组成❄️2.3 HTML 是什么❄️2.4html基本结构 🌍三.HTML标签1.html 的标签/元素-说明2. html 标签注意事项和细节3.font 字体标签4.标题标签5.超链接标签…

点亮一个esp32 的led

最近入了一个ESP32 兄弟们,这玩意还可以,买来肯定是给它点亮啊对吧 我就是点灯侠🎇 😭千万不要不接天线啊,不然你会一直找不到你的wifi 1.点灯第一步你得有IDE Arduino 就是这个绿东西 可是怎么下载安装呢&#xff…

CI/CD 流水线

CI/CD 流水线 CI 与 CD 的边界CI 持续集成CD(持续交付/持续部署)自动化流程示例: Jenkins 引入到 CI/CD 流程在本地或服务器上安装 Jenkins。配置 Jenkins 环境流程设计CI 阶段:Jenkins 流水线实现CD 阶段:Jenkins 流水…

HTB:Bastion[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 将靶机TCP开放端口号提取并保存 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 使用enum4linux…

Springboot——钉钉(站内)实现登录第三方应用

文章目录 前言准备1、创建钉钉应用,并开放网页应用2、配置网页应用各项参数发布版本 前端改造后端逻辑1、获取应用免登录 Access_token2、通过免登录 Access_token 和 Auth_Code 获取对应登录人信息 注意事项 前言 PC端的钉钉中工作台,增加第三方应用&a…

马斯克的Grok-2 Beta APP在苹果应用商店上限了,Grok-2安装尝鲜使用教程

马斯克的Grok-2 Beta APP 已经上线苹果商城了,移动端的Grok挺好用的!无需登录即可使用! (文末有安装教程) 实测之后,Grok-2 绘画方面个人感觉比GPT-4的绘画还要强一些。而且速度还挺快,可以多次…

深入理解 C 语言中浮点型数据在内存中的存储

文章目录 一、浮点型数据存储格式(IEEE 754 标准)二、举例说明单精度浮点数存储过程三、绘图说明四、双精度浮点数存储示例(以1.5为例) 在 C 语言的世界里,数据类型丰富多样,而浮点型数据用于表示实数&…

hutool糊涂工具通过注解设置excel宽度

import java.lang.annotation.*;Documented Retention(RetentionPolicy.RUNTIME) Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) public interface ExcelStyle {int width() default 0; }/*** 聊天记录*/ Data public class DialogContentInfo {/**…

自定义日期转换配置

文章目录 1.日期问题出现原因以及解决方案概述1.图示2.三种解决方案概述1.对于表单数据 application/x-www-form-urlencoded2.对于JSON数据1.使用JsonFormat注解2.自定义Jackson日期转换配置 2.解决方案common-web-starter1.目录2.BaseController.java 使用InitBinder解决表单数…

Ubuntu更改内核

需求背景: 由于软件需要在较低版本或者指定版本才可以运行 版本: 配置文件: vi /etc/default/grub 启动界面: 可运行版本: 解决方案: 方案1、更改启动顺序 sudo vi /etc/default/grub 方案2、调整启动顺…

Android系统定制APP开发_如何对应用进行系统签名

前言 当项目开发需要使用系统级别权限或frame层某些api时,普通应用是无法使用的,需要在AndroidManifest中配置sharedUserId: AndroidManifest.xml中的android:sharedUserId“android.uid.system”,代表的意思是和系统相同的uid&a…

解决idea中无法拖动tab标签页的问题

1、按 Ctrl Alt S 打开设置,找到路径 File | Settings | Appearance & Behavior | Appearance 2、去掉勾选 Drag-and-drop with Alt pressed only 即可