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

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.tpcf.cn/pingmian/67044.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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 的首页,持续学…

Flask-SQLAlchemy 基础用法

1 安装 Flask-SQLAlchemy 首先,确保您已安装 Flask 和 Flask-SQLAlchemy: pip install Flask Flask-SQLAlchemy2 创建 Flask 应用 创建一个基本的 Flask 应用结构: from flask import Flask from flask_sqlalchemy import SQLAlchemyapp …

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…

std::array

std::array 是 C 标准库中的一个容器&#xff0c;定义在 <array> 头文件中。它是一个固定大小的数组容器&#xff0c;封装了 C 风格数组&#xff0c;并提供了更多的功能和安全性。与 C 风格数组相比&#xff0c;std::array 具有以下优点&#xff1a; &#xff08;1&#…

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

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

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

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

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更改内核

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