Python设计模式 - 组合模式
定义
组合模式(Composite Pattern) 是一种结构型设计模式,主要意图是将对象组织成树形结构以表示"部分-整体"的层次结构。这种模式能够使客户端统一对待单个对象和组合对象,从而简化了客户端代码。
组合模式有透明组合模式和安全组合模式两种,下面分别介绍这两种模式。
透明组合模式
结构
- 组件(Component):组件是组合中的抽象类或接口,它声明了叶子节点和组合节点的公共接口,以确保客户端可以统一对待单个对象和组合对象。组件通常包含一些操作方法,如添加子节点、删除子节点、获取子节点等。
- 叶子节点(Leaf):叶子节点是组合中的叶子对象,它没有子节点。叶子节点实现了组件接口,并提供了具体的操作方法。叶子节点表示组合中的最小单元,是组合结构中不可再分的基本元素。
- 组合节点(Composite):组合节点是组合中的复合对象,它可以包含其他组件作为子节点。组合节点也实现了组件接口,并提供了与叶子节点相同的操作方法。组合节点表示组合结构中的内部节点,可以包含其他子节点。
应用场景
- 树形结构表示:当你的问题领域可以自然地表示为树形结构时,透明组合模式是一个很好的选择。例如,文件系统、组织结构等都可以使用透明组合模式来表示。
- 部分-整体关系:当你的问题领域中存在明显的部分-整体关系时,透明组合模式可以帮助你更好地表示和处理这种关系。例如,产品和其部件、图形和其组成元素等都可以使用透明组合模式来表示。
优缺点
优点:
- 简化客户端代码:透明组合模式使客户端能够统一对待单个对象和组合对象,从而简化了客户端代码。客户端不需要关心对象的具体类型,而是统一使用相同的接口来操作对象。
- 灵活性:透明组合模式允许你在运行时动态地添加、移除和修改对象的组合结构,从而提供了更大的灵活性。你可以方便地调整对象之间的层次关系,以满足不同的需求。
- 可扩展性:由于透明组合模式将叶子节点和组合节点都视为相同类型的对象,因此很容易添加新的节点类型,而不会影响到现有的代码。这提高了系统的可扩展性。
缺点:
- 限制性:透明组合模式要求叶子节点和组合节点实现相同的接口,这可能会限制叶子节点和组合节点的设计和扩展。有时候,这种限制可能会影响到系统的设计和灵活性。
- 性能问题:组合模式可能会带来一些性能问题,特别是在处理大型的对象组合结构时的遍历性能。这包括遍历性能、内存占用等方面的问题,可能会影响系统的性能表现。
代码示例
from abc import ABC, abstractmethod# 抽象组件类
class Component(ABC):@abstractmethoddef add(self, component):pass@abstractmethoddef remove(self, component):pass@abstractmethoddef scan(self):pass# 叶子节点类:文件
class File(Component):def __init__(self, name):self.name = namedef add(self, component):raise NotImplementedError('文件不支持添加子组件')def remove(self, component):raise NotImplementedError('文件不支持移除子组件')def scan(self):print("正在扫描文件:", self.name)# 组合节点类:文件夹
class Folder(Component):def __init__(self, name):self.name = nameself.children = []def add(self, component):self.children.append(component)def remove(self, component):self.children.remove(component)def scan(self):print("正在扫描文件夹:", self.name)for child in self.children:child.scan()# 客户端代码
if __name__ == "__main__":# 创建文件和文件夹对象file1 = File("file1.txt")file2 = File("file2.txt")folder1 = Folder("folder1")folder2 = Folder("folder2")# 将文件添加到文件夹中folder1.add(file1)folder2.add(file2)# 将文件夹添加到文件夹中root_folder = Folder("root")root_folder.add(folder1)root_folder.add(folder2)# 扫描根文件夹root_folder.scan()
安全组合模式
安全组合模式是组合模式的一种变体,它与透明组合模式相比,区别在于它将管理子节点的方法从抽象组件中移除,使得叶子节点和组合对象的接口不再相同,从而更加安全。
结构
- Component(组件):定义了叶子节点和组合对象的公共接口,可以包含一些默认的行为。这个接口通常包括操作方法,如 operation(),但不包括管理子节点的方法。
- Leaf(叶子节点):表示组合中的叶子对象,没有子节点,实现了 Component 接口。通常,叶子节点执行最终的操作。
- Composite(组合对象):表示组合中的容器对象,可以包含子节点,也实现了 Component 接口。它负责管理子节点,包括添加、删除和获取子节点等操作。
应用场景
使用场景和透明组合模式一样:
- 树形结构表示:当你的问题领域可以自然地表示为树形结构时,透明组合模式是一个很好的选择。例如,文件系统、组织结构等都可以使用透明组合模式来表示。
- 部分-整体关系:当你的问题领域中存在明显的部分-整体关系时,透明组合模式可以帮助你更好地表示和处理这种关系。例如,产品和其部件、图形和其组成元素等都可以使用透明组合模式来表示。
如何选择使用透明组合模式还是安全组合模式:
对于简单的情况和对接口一致性要求较高的情况,透明组合模式可能更为适用。而对于复杂的情况和对接口分离性要求较高的情况,安全组合模式可能更为合适,因为它可以明确区分组合对象和叶子对象的接口,提高了安全性和灵活性。
优缺点
优点:
- 接口隔离性强:安全组合模式明确区分了组合对象和叶子对象的接口,使得客户端只能通过组合对象来操作子节点,从而提高了接口的隔离性。
- 安全性高:由于叶子对象的接口不再包含管理子节点的方法,安全组合模式可以更好地防止客户端直接对叶子对象进行不安全的操作,从而提高了系统的安全性。
- 灵活性增强:安全组合模式允许组合对象和叶子对象的接口可以根据实际需求进行灵活设计,使得系统更容易扩展和维护。
缺点:
- 使用复杂度增加:相比于透明组合模式,安全组合模式引入了额外的接口和方法,可能会增加系统的使用复杂度和理解成本。
- 性能问题:组合模式可能会带来一些性能问题,特别是在处理大型的对象组合结构时的遍历性能。这包括遍历性能、内存占用等方面的问题,可能会影响系统的性能表现。
代码示例
from abc import ABC, abstractmethod# 抽象组件类
class Component(ABC):@abstractmethoddef scan(self):pass# 叶节点类:文件
class File(Component):def __init__(self, name):self.name = namedef scan(self):print("正在扫描文件:", self.name)# 组合节点类:文件夹
class Folder(Component):def __init__(self, name):self.name = nameself.children = []def add(self, component):self.children.append(component)def remove(self, component):self.children.remove(component)def scan(self):print("正在扫描文件夹:", self.name)for child in self.children:child.scan()# 客户端代码
if __name__ == "__main__":# 创建文件和文件夹对象file1 = File("file1.txt")file2 = File("file2.txt")folder1 = Folder("folder1")folder2 = Folder("folder2")# 将文件添加到文件夹中folder1.add(file1)folder2.add(file2)# 将文件夹添加到文件夹中root_folder = Folder("root")root_folder.add(folder1)root_folder.add(folder2)# 扫描根文件夹root_folder.scan()
参考
《设计模式的艺术》
相关文章:

Python设计模式 - 组合模式
定义 组合模式(Composite Pattern) 是一种结构型设计模式,主要意图是将对象组织成树形结构以表示"部分-整体"的层次结构。这种模式能够使客户端统一对待单个对象和组合对象,从而简化了客户端代码。 组合模式有透明组合…...

css粘性定位超出指定宽度失效问题
展示效果 解决办法:外层容器添加display:grid即可 完整代码 <template><div class"box"><div class"line" v-for"items in 10"><div class"item" v-for"item in 8">drgg</div>&…...

Windows 程序设计6:错误码的查看
文章目录 前言一、说明二、使用GetLastError找到错误的原因三、使用错误码的宏总结 前言 Windows 程序设计6:错误码的查看。 一、说明 有时写的代码单纯看是没有问题的,但是执行起来就会崩溃。因此要养成判断函数执行是否成功的习惯,除非这…...

doris: CSV导入数据
本文介绍如何在 Doris 中导入 CSV 格式的数据文件。Doris 支持灵活的 CSV 格式配置,包括自定义分隔符、字段包围符等,并提供多种导入方式以满足不同场景的数据导入需求。 导入方式 Doris 支持以下方式导入 CSV 格式数据: Stream LoadBro…...

FastStone Image Viewer图像处理软件安装步骤(百度网盘链接)
软件简介:一款小巧便捷的添加水印、特效、图片处理软件,让使用者可以通过它的操作界面来浏览图片,且还支持了幻灯播放的功能,让使用者能够轻松的浏览目录中的所有图片。 网盘链接:https://pan.baidu.com/s/1Zvrx7fXwb6…...

Kafka 深入服务端 — 时间轮
Kafka中存在大量的延迟操作,比如延时生产、延时拉取和延时删除等。Kafka基于时间轮概念自定义实现了一个用于延时功能的定时器,来完成这些延迟操作。 1 时间轮 Kafka没有使用基于JDK自带的Timer或DelayQueue来实现延迟功能,因为它们的插入和…...

网络爬虫学习:应用selenium获取Edge浏览器版本号,自动下载对应版本msedgedriver,确保Edge浏览器顺利打开。
一、前言 我从24年11月份开始学习网络爬虫应用开发,经过2个来月的努力,于1月下旬完成了开发一款网络爬虫软件的学习目标。这里对本次学习及应用开发进行一下回顾总结。 前几天我已经发了一篇日志(网络爬虫学习:应用selenium从搜…...

【go语言】结构体
一、type 关键字的用法 在 go 语言中,type 关键字用于定义新的类型,他可以用来定义基础类型、结构体类型、接口类型、函数类型等。通过 type 关键字,我们可以为现有类型创建新的类型别名或者自定义新的类型。 1.1 类型别名 使用 type 可以为…...

Spring Boot是什么及其优点
简介 Spring Boot是基于Spring框架开发的全新框架,其设计目的是简化Spring应用的初始化搭建和开发过程。 Spring Boot整合了许多框架和第三方库配置,几乎可以达到“开箱即用”。 优点 可快速构建独立的Spring应用。 直接嵌入Tomcat、Jetty和Underto…...

谷氨酸:大脑功能的多面手
标题:谷氨酸:大脑功能的多面手 文章信息摘要: 谷氨酸是大脑中最主要的兴奋性神经递质,参与了90%以上的神经元激活,在蛋白质合成、味觉(鲜味)以及神经可塑性中发挥重要作用。它与GABA、多巴胺等…...

SpringCloudGateWay和Sentinel结合做黑白名单来源控制
假设我们的分布式项目,admin是8087,gateway是8088,consumer是8086 我们一般的思路是我们的请求必须经过我们的网关8088然后网关转发到我们的分布式项目,那我要是没有处理我们绕过网关直接访问项目8087和8086不也是可以࿱…...

HTML新春烟花
系列文章 序号目录1HTML满屏跳动的爱心(可写字)2HTML五彩缤纷的爱心3HTML满屏漂浮爱心4HTML情人节快乐5HTML蓝色爱心射线6HTML跳动的爱心(简易版)7HTML粒子爱心8HTML蓝色动态爱心9HTML跳动的爱心(双心版)10…...

【Elasticsearch】中数据流需要配置索引模板吗?
是的,数据流需要配置索引模板。在Elasticsearch中,数据流(Data Streams)是一种用于处理时间序列数据的高级结构,它背后由多个隐藏的索引组成,这些索引被称为后备索引(Backing Indices࿰…...

Git进阶之旅:Git 配置信息 Config
Git 配置级别: 仓库级别:local [ 优先级最高 ]用户级别:global [ 优先级次之 ]系统级别:system [ 优先级最低 ] 配置文件位置: git 仓库级别对应的配置文件是当前仓库下的 .git/configgit 用户级别对应的配置文件时用…...

buu-pwn1_sctf_2016-好久不见29
这个也是栈溢出,不一样的点是,有replace替换,要输入0x3c字符(60),Iyou 所以,20个I就行,找后面函数 输出提示信息,要求用户输入关于自己的信息。 使用fgets函数从标准输入…...

ES2021+新特性、常用函数
一、ES2021新特性 ES2021 数字分隔符 let num 1234567 let num2 1_234_567 Promise.any 与 Promise.all 类似,Promise.any 也接受一个 Promise 的数组。当其中任何一个 Promise 完成(fullfill)时,就返回那个已经有完成值的 …...

STM32——LCD
一、引脚配置 查看引脚 将上述引脚都设置为GPIO_Output 二、导入驱动文件 将 LCD 驱动的 Inc 以及 Src 中的 fonts.h,lcd.h 和 lcd.c 导入到自己工程的驱动文件中。 当然,后面 lcd 的驱动学习可以和 IMX6U 一块学。 三、LCD函数 void LCD_Clear(u16 Color); 功能…...

【redis进阶】分布式锁
目录 一、什么是分布式锁 二、分布式锁的基础实现 三、引入过期时间 四、引入校验 id 五、引入lua 六、引入 watch dog (看门狗) 七、引入 Redlock 算法 八、其他功能 redis学习🥳 一、什么是分布式锁 在一个分布式的系统中,也会涉及到多个节点访问同一…...

园区管理系统如何提升企业核心竞争力与资产管理智能化水平
内容概要 在当今快节奏的商业环境中,园区管理系统正成为企业的重要合作伙伴,尤其在工业园、产业园、物流园、写字楼和公寓等多种类型的物业管理中。这个系统不仅仅是一个管理工具,它还是提升企业运营效率和核心竞争力的关键因素。通过智能化…...

AI大模型开发原理篇-3:词向量和词嵌入
简介 词向量是用于表示单词意义的向量, 并且还可以被认为是单词的特征向量或表示。 将单词映射到实向量的技术称为词嵌入。在实际应用中,词向量和词嵌入这两个重要的NLP术语通常可以互换使用。它们都表示将词汇表中的单词映射到固定大小的连续向量空间中…...

高精度算法:高精度减法
P2142 高精度减法 - 洛谷 | 计算机科学教育新生态 我们两个整数一定要是大数减去小数,所以这个点我们需要特判一下,那我们两个字符串表示的整型怎么判断大小呢,我们字典序比较大小和真实的数字比较大小是一样的,比如我们的‘21’…...

Java创建项目准备工作
新建项目 新建空项目 每一个空项目创建好后都要检查jdk版本 检查SDK和语言级别——Apply——OK 检查当前项目的Maven路径,如果已经配置好全局,就是正确路径不用管 修改项目字符集编码,将所有编码都调整为UTF-8 创建Spingboot工程 创建Spring…...

基于STM32的智能宠物喂食器设计
目录 引言系统设计 硬件设计软件设计 系统功能模块 定时喂食模块远程控制与视频监控模块食物存量检测与报警模块语音互动与用户交互模块数据记录与智能分析模块 控制算法 定时与手动投喂算法食物存量检测与低存量提醒算法数据记录与远程反馈算法 代码实现 喂食控制代码存量检测…...

在线课堂小程序设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...

为AI聊天工具添加一个知识系统 之77 详细设计之18 正则表达式 之5
本文要点 昨天讨论了 本项目(AI聊天工具添加一个知识系统)中正则表达式模板的设计中可能要考虑到的一些问题(讨论到的内容比较随意,暂时无法确定 那些考虑 是否 应该是正则表达式模板设计要考虑的以及 是否完整)。今天…...

【Elasticsearch】 索引模板 ignore_missing_component_templates
解释 ignore_missing_component_templates 配置 在Elasticsearch中,ignore_missing_component_templates 是一个配置选项,用于处理索引模板中引用的组件模板可能不存在的情况。当您创建一个索引模板时,可以指定一个或多个组件模板࿰…...

Github 2025-01-29 C开源项目日报 Top10
根据Github Trendings的统计,今日(2025-01-29统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目10C++项目1Assembly项目1Go项目1我的电视 - 安卓电视直播软件 创建周期:40 天开发语言:CStar数量:649 个Fork数量:124 次关注人数:64…...

文件上传2
BUUCTF 你传你🐎呢 先上传.htaccess 修改格式 即可上传成功 返回上传图片格式的木马 用蚁剑连接 5ecf1cca-59a1-408b-b616-090edf124db5.node5.buuoj.cn:81/upload/7d8511a847edeacb5385299396a96d91/rao.jpg 即可得到flag [GXYCTF2019]BabyUpload...

Unity敌人逻辑笔记
写ai逻辑基本上都需要状态机。因为懒得手搓状态机,所以选择直接用动画状态机当逻辑状态机用。 架构设计 因为敌人的根节点已经有一个animator控制动画,只能增加一个子节点AI,给它加一个animator指向逻辑“动画”状态机。还有一个脚本&#…...

高级编码参数
1.跳帧机制 参考资料:frameskipping-hotedgevideo 跳帧机制用于优化视频质量和编码效率。它通过选择性地跳过某些帧并使用参考帧来预测和重建视频内容,从而减少编码所需的比特率,同时保持较高的视频质量。在视频编码过程中,如果…...