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

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

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. 组合模式简化客户端代码,使其更加灵活

相关文章:

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

1. 什么是组合模式? 组合模式(Composite Pattern) 是一种结构型设计模式,它允许将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得客户端对单个对象和组合对象的使用具有一致性。换句话说,组合模式允…...

基于Java的推箱子游戏设计与实现

基于Java的推箱子游戏设计与实现 摘 要 社会在进步,人们生活质量也在日益提高。高强度的压力也接踵而来。社会中急需出现新的有效方式来缓解人们的压力。此次设计符合了社会需求,Java推箱子游戏可以让人们在闲暇之余,体验游戏的乐趣。具有…...

Spark vs Flink分布式数据处理框架的全面对比与应用场景解析

1. 引言 1.1 什么是分布式数据处理框架 随着数据量的快速增长,传统的单机处理方式已经无法满足现代数据处理需求。分布式数据处理框架应运而生,它通过将数据分片分布到多台服务器上并行处理,提高了任务的处理速度和效率。 分布式数据处理框…...

python_excel列表单元格字符合并、填充、复制操作

读取指定sheet页,根据规则合并指定列,填充特定字符,删除多余的列,每行复制四次,最后写入新的文件中。 import pandas as pd""" 读取指定sheet页,根据规则合并指定列,填充特定字…...

nums[:]数组切片

问题:给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 使用代码如下没有办法通过测试示例,必须将最后一行代码改成 nums[:]nums[-k:]nums[:-k]切片形式: 原因:列表的切片操作 …...

【Arthas 】Can not find Arthas under local: /root/.arthas/lib 解决办法

报错 [INFO] JAVA_HOME: /opt/java/openjdk [INFO] arthas-boot version: 4.0.4 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. [1]: 12 org.springframework.boot.loader.JarLauncher 1 [ER…...

录用率23%!CCF推荐-B类,Early Access即可被SCI数据库收录,中美作者占比过半

International Journal of Human-Computer Interaction(IJHCI)创刊于1989年,由泰勒-弗朗西斯(Taylor & Francis, Inc.)出版,主要发表关于交互式计算(认知和人体工程学)、数字无障…...

IP 地址与蜜罐技术

基于IP的地址的蜜罐技术是一种主动防御策略,它能够通过在网络上布置的一些看似正常没问题的IP地址来吸引恶意者的注意,将恶意者引导到预先布置好的伪装的目标之中。 如何实现蜜罐技术 当恶意攻击者在网络中四处扫描,寻找可入侵的目标时&…...

Vue_API文档

Vue API风格 Vue 的组件可以按两种不同的风格书写:选项式 API(Vue2) 和组合式 API(Vue3) 大部分的核心概念在这两种风格之间都是通用的。熟悉了一种风格以后,你也能够很快地理解另一种风格 选项式API(Opt…...

WebSocket 设计思路

WebSocket 设计思路 1. 核心结构体 1.1 Manager (管理器) // Manager 负责管理所有WebSocket连接 type Manager struct {clients sync.Map // 存储所有客户端连接broadcast chan []byte // 广播消息通道messages chan Message // 消息处理通道config *config.WebSo…...

Jenkins持续集成与交付安装配置

Jenkins 是一款开源的持续集成(CI)和持续交付(CD)工具,它主要用于自动化软件的构建、测试和部署流程。为项目持续集成与交付功能强大的应用。下面我们来介绍下它的安装与配置。 环境准备 更新系统组件(这…...

ESP32作为Wi-Fi AP模式的测试

一、AP模式的流程 初始化阶段 (Init Phase): 1.1: Main task(主任务)初始化LwIP(轻量级TCP/IP协议栈)。 ESP_ERROR_CHECK(esp_netif_init()); 1.2: 创建和初始化Event task(事件任务)。 ESP_ERROR_CHECK…...

【爬虫】单个网站链接爬取文献数据:标题、摘要、作者等信息

源码链接: https://github.com/Niceeggplant/Single—Site-Crawler.git 一、项目概述 从指定网页中提取文章关键信息的工具。通过输入文章的 URL,程序将自动抓取网页内容 二、技术选型与原理 requests 库:这是 Python 中用于发送 HTTP 请求…...

Android RIL(Radio Interface Layer)全面概述和知识要点(3万字长文)

在Android面试时,懂得越多越深android framework的知识,越为自己加分。 目录 第一章:RIL 概述 1.1 RIL 的定义与作用 1.2 RIL 的发展历程 1.3 RIL 与 Android 系统的关系 第二章:RIL 的架构与工作原理 2.1 RIL 的架构组成 2.2 RIL 的工作原理 2.3 RIL 的接口与协议…...

leetcode_2816. 翻倍以链表形式表示的数字

2816. 翻倍以链表形式表示的数字 - 力扣(LeetCode) 搜先看到这个题目 链表的节点那么多 已经远超longlong能够表示的范围 那么暴力解题 肯定是不可以的了 我们可以想到 乘法运算中 就是从低位到高位进行计算 刚开始 我想先反转链表 然后在计算 然后在进…...

【论文阅读】MAMBA系列学习

Mamba code:state-spaces/mamba: Mamba SSM architecture paper:https://arxiv.org/abs/2312.00752 背景 研究问题:如何在保持线性时间复杂度的同时,提升序列建模的性能,特别是在处理长序列和密集数据(如…...

MySQL教程之:批量使用mysql

在前几节中&#xff0c;您以交互方式使用mysql输入语句并查看结果。您也可以运行mysql批量模式。为此&#xff0c;请将要运行的语句放在文件中&#xff0c;然后告诉mysql从文件中读取其输入&#xff1a; $> mysql < batch-file 如果您在Windows下运行mysql&#xff0c;…...

17_Redis管道技术

Redis管道(Pipeline)技术是一种在 Redis 客户端与服务器之间进行高效数据交互的技术。 1.Redis管道技术介绍 1.1 传统请求响应模式 在传统的请求-响应模式下,客户端每发送一个命令后会等待服务器返回结果,然后再发送下一个命令。这种方式在网络延迟较高的情况下会导致性…...

【LC】3270. 求出数字答案

题目描述&#xff1a; 给你三个 正 整数 num1 &#xff0c;num2 和 num3 。 数字 num1 &#xff0c;num2 和 num3 的数字答案 key 是一个四位数&#xff0c;定义如下&#xff1a; 一开始&#xff0c;如果有数字 少于 四位数&#xff0c;给它补 前导 0 。答案 key 的第 i 个数…...

【redis】ubuntu18安装redis7

在Ubuntu 18下安装Redis7可以通过以下两种方法实现&#xff1a;手动编译安装和使用APT进行安装。 Ubuntu 18系统的环境和版本&#xff1a; $ cat /proc/version Linux version 4.15.0-213-generic (builddlcy02-amd64-079) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...