Python设计模式 - 组合模式

定义

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

组合模式有透明组合模式和安全组合模式两种,下面分别介绍这两种模式。

透明组合模式

结构

在这里插入图片描述

  • 组件(Component):组件是组合中的抽象类或接口,它声明了叶子节点和组合节点的公共接口,以确保客户端可以统一对待单个对象和组合对象。组件通常包含一些操作方法,如添加子节点、删除子节点、获取子节点等。
  • 叶子节点(Leaf):叶子节点是组合中的叶子对象,它没有子节点。叶子节点实现了组件接口,并提供了具体的操作方法。叶子节点表示组合中的最小单元,是组合结构中不可再分的基本元素。
  • 组合节点(Composite):组合节点是组合中的复合对象,它可以包含其他组件作为子节点。组合节点也实现了组件接口,并提供了与叶子节点相同的操作方法。组合节点表示组合结构中的内部节点,可以包含其他子节点。

应用场景

  1. 树形结构表示:当你的问题领域可以自然地表示为树形结构时,透明组合模式是一个很好的选择。例如,文件系统、组织结构等都可以使用透明组合模式来表示。
  2. 部分-整体关系:当你的问题领域中存在明显的部分-整体关系时,透明组合模式可以帮助你更好地表示和处理这种关系。例如,产品和其部件、图形和其组成元素等都可以使用透明组合模式来表示。

优缺点

优点:

  1. 简化客户端代码:透明组合模式使客户端能够统一对待单个对象和组合对象,从而简化了客户端代码。客户端不需要关心对象的具体类型,而是统一使用相同的接口来操作对象。
  2. 灵活性:透明组合模式允许你在运行时动态地添加、移除和修改对象的组合结构,从而提供了更大的灵活性。你可以方便地调整对象之间的层次关系,以满足不同的需求。
  3. 可扩展性:由于透明组合模式将叶子节点和组合节点都视为相同类型的对象,因此很容易添加新的节点类型,而不会影响到现有的代码。这提高了系统的可扩展性。

缺点:

  1. 限制性:透明组合模式要求叶子节点和组合节点实现相同的接口,这可能会限制叶子节点和组合节点的设计和扩展。有时候,这种限制可能会影响到系统的设计和灵活性。
  2. 性能问题:组合模式可能会带来一些性能问题,特别是在处理大型的对象组合结构时的遍历性能。这包括遍历性能、内存占用等方面的问题,可能会影响系统的性能表现。

代码示例

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 接口。它负责管理子节点,包括添加、删除和获取子节点等操作。

应用场景

使用场景和透明组合模式一样:

  1. 树形结构表示:当你的问题领域可以自然地表示为树形结构时,透明组合模式是一个很好的选择。例如,文件系统、组织结构等都可以使用透明组合模式来表示。
  2. 部分-整体关系:当你的问题领域中存在明显的部分-整体关系时,透明组合模式可以帮助你更好地表示和处理这种关系。例如,产品和其部件、图形和其组成元素等都可以使用透明组合模式来表示。

如何选择使用透明组合模式还是安全组合模式:

对于简单的情况和对接口一致性要求较高的情况,透明组合模式可能更为适用。而对于复杂的情况和对接口分离性要求较高的情况,安全组合模式可能更为合适,因为它可以明确区分组合对象和叶子对象的接口,提高了安全性和灵活性。

优缺点

优点:

  1. 接口隔离性强:安全组合模式明确区分了组合对象和叶子对象的接口,使得客户端只能通过组合对象来操作子节点,从而提高了接口的隔离性。
  2. 安全性高:由于叶子对象的接口不再包含管理子节点的方法,安全组合模式可以更好地防止客户端直接对叶子对象进行不安全的操作,从而提高了系统的安全性。
  3. 灵活性增强:安全组合模式允许组合对象和叶子对象的接口可以根据实际需求进行灵活设计,使得系统更容易扩展和维护。

缺点:

  1. 使用复杂度增加:相比于透明组合模式,安全组合模式引入了额外的接口和方法,可能会增加系统的使用复杂度和理解成本。
  2. 性能问题:组合模式可能会带来一些性能问题,特别是在处理大型的对象组合结构时的遍历性能。这包括遍历性能、内存占用等方面的问题,可能会影响系统的性能表现。

代码示例

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()

参考

《设计模式的艺术》

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

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

相关文章

Java 基于 SpringBoot 的校园外卖点餐平台微信小程序(附源码,部署,文档)

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

当高兴、尊重和优雅三位一体是什么情况吗?

英语单词 disgrace 表示“失脸,耻辱,不光彩,名誉扫地”一类的含义,可做名词或动词使用,含义基本一致,只是词性不同。 disgrace n.丢脸;耻辱;不光彩;令人感到羞耻的人(或…

LeetCode热题100(八)—— 438.找到字符串中所有字母异位词

LeetCode热题100(八)—— 438.找到字符串中所有字母异位词 题目描述代码实现思路解析 你好,我是杨十一,一名热爱健身的程序员在Coding的征程中,不断探索与成长LeetCode热题100——刷题记录(不定期更新&…

八股——Java基础(四)

目录 一、泛型 1. Java中的泛型是什么 ? 2. 使用泛型的好处是什么? 3. Java泛型的原理是什么 ? 什么是类型擦除 ? 4.什么是泛型中的限定通配符和非限定通配符 ? 5. List和List 之间有什么区别 ? 6. 可以把List传递给一个接受List参数的方法吗? 7. Arra…

naivecv的设计与实现(2): 读写gray和rgb图像

图像读写并不是图像处理的核心,仅仅作为调试工具, 是一种手段而非目的。 图像文件格式的选择 正因如此,对gray和rgb图像的读写,存在多种方法。 最常见的三种图像文件格式: bmppngjpg 实际上有更简单的方式&#xf…

设计壁纸时,色彩选择是至关重要的一步

在设计壁纸时,色彩选择是至关重要的一步,它直接影响到壁纸的整体视觉效果和情感传达。以下是一些色彩选择的技巧,帮助你在设计中更好地运用色彩: 一、了解色彩理论 色彩轮: 基本颜色:红、黄、蓝是三原色&am…

二次封装的方法

二次封装 我们开发中经常需要封装一些第三方组件,那么父组件应该怎么传值,怎么调用封装好的组件原有的属性、插槽、方法,一个个调用虽然可行,但十分麻烦,我们一起来看更简便的方法。 二次封装组件,属性怎…

c++多态

1.多态的概念 通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。 2.多态的定义及实现 2.1多态的构成条件 多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为…

docker安装Redis:docker离线安装Redis、docker在线安装Redis、Redis镜像下载、Redis配置、Redis命令

一、镜像下载 1、在线下载 在一台能连外网的linux上执行docker镜像拉取命令 docker pull redis:7.4.0 2、离线包下载 两种方式: 方式一: -)在一台能连外网的linux上安装docker执行第一步的命令下载镜像 -)导出 # 导出镜像…

【unity游戏开发之InputSystem——07】InputSystem+UGUI配合使用(基于unity6开发介绍)

文章目录 一、InputSystem+UGUI配合使用1、官方文档参考2、切换到新的输入模块二、UGUI中的新输入系统输入模块参数相关1、Send Pointer Hover To Parent2、Move Repeat Delay3、Move Repeat Rate4、XR Tracking Origin5、Deselect On Background CLick6、Pointer Behavior7、S…

国内优秀的FPGA设计公司主要分布在哪些城市?

近年来,国内FPGA行业发展迅速,随着5G通信、人工智能、大数据等新兴技术的崛起,FPGA设计企业的需求也迎来了爆发式增长。很多技术人才在求职时都会考虑城市的行业分布和发展潜力。因此,国内优秀的FPGA设计公司主要分布在哪些城市&a…

汇编基础语法及其示例

1.汇编指令 1.1汇编指令的基本格式 <opcode>{<cond>}{s} <Rd> , <Rn> , <shifter_operand> <功能码>{<条件码>}{cpsr影响位} <目标寄存器> , <第一操作寄存器> , <第二操作数> 注&#xff1a;第一操作寄存器…

Direct2D 极速教程(1) —— 画图形

极速导航 Direct2D 简介创建新项目&#xff1a;001-DrawGraphics弄一个白窗口在窗口上画图 Direct2D 简介 大家在学 WINAPI 的时候的时候有没有想过&#xff0c;怎么在一副窗口上画图呢&#xff1f;大家知道 Windows 系统是 GUI 图形用户界面 系统&#xff0c;以 Graphics 图形…

Linux之详谈——权限管理

目录 小 峰 编 程 ​编辑 一、权限概述 1、什么是权限 2、为什么要设置权限 3、Linux中的权限类别- 4、Linux中文件所有者 1&#xff09;所有者分类&#xff08;谁&#xff09; 2&#xff09;所有者的表示方法 ① u(the user who owns it)&#xff08;属主权限&…

基于金融新闻的大型语言模型强化学习在投资组合管理中的应用

“Financial News-Driven LLM Reinforcement Learning for Portfolio Management” 论文地址&#xff1a;https://arxiv.org/pdf/2411.11059 摘要 本研究探索了如何通过将大语言模型&#xff08;LLM&#xff09;支持的情感分析融入强化学习&#xff08;RL&#xff09;中&#…

K8s运维管理平台 - KubeSphere 3.x 和4.x 使用分析:功能较强,UI美观

目录标题 Lic使用感受优点&#xff1a;优化点&#xff1a; 实操首页项目 | 应用负载 | 配置 | 定制资源定义存储监控告警集群设置 **KubeSphere 3.x** 和 **4.x**1. **架构变化**&#xff1a;2. **多集群管理**&#xff1a;3. **增强的 DevOps 功能**&#xff1a;4. **监控与日…

当AI学会“顿悟”:DeepSeek-R1如何用强化学习突破推理边界?

开篇&#xff1a;一场AI的“青春期叛逆” 你有没有想过&#xff0c;AI模型在学会“推理”之前&#xff0c;可能也经历过一段“中二时期”&#xff1f;比如&#xff0c;解题时乱写一通、语言混搭、答案藏在火星文里……最近&#xff0c;一支名为DeepSeek-AI的团队&#xff0c;就…

Ollama+DeepSeek本地大模型部署

1、Ollama 官网&#xff1a;https://ollama.com/ Ollama可以干什么&#xff1f; 可以快速在本地部署和管理各种大语言模型&#xff0c;操作命令和dokcer类似。 mac安装ollama&#xff1a; # 安装ollama brew install ollama# 启动ollama服务&#xff08;默认11434端口&#xf…

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(三)

Understanding Diffusion Models: A Unified Perspective&#xff08;三&#xff09; 文章概括 文章概括 引用&#xff1a; article{luo2022understanding,title{Understanding diffusion models: A unified perspective},author{Luo, Calvin},journal{arXiv preprint arXiv:…

mybatis(104/134)

动态sql标签&#xff0c;用于选择查询 if标签 where标签 &#xff1a;自动生成where&#xff0c;取决于后面有没有条件&#xff0c;会自动去除条件前面的and和or&#xff0c;不会去除语句后面的 trim标签&#xff1a;自动生成where&#xff0c;在语句后自动去除后缀and和or for…