组合模式(Composite Pattern)
非常棒!你现在进入了结构型设计模式中最典型的「树形结构」设计模式 —— 组合模式(Composite Pattern)。
我将通过简明解释 + 清晰代码 + 类图演示,一步步帮你理解它。
🧠 一句话定义
组合模式允许你将对象组合成树形结构来表示“整体-部分”的层次结构,客户端对单个对象和组合对象使用一致的方式处理。
🎯 生活类比
你有一个文件夹,里面可以包含:
- 文件(不可分)
- 子文件夹(可以再包含文件/子文件夹)
你希望:
✅ 用一样的方式对文件和文件夹进行操作(比如查看大小、遍历等)
这就是组合模式的典型应用!
✅ 为什么需要组合模式?
问题 | 组合模式的解决 |
---|---|
对象和容器对象要统一处理 | 定义统一接口 Component |
容器嵌套容器,不方便操作 | 用递归统一管理结构 |
添加层次后代码爆炸 | 容器类和单元类都实现统一接口,客户端不需要 if 判断 |
✅ 优点 vs ❌ 缺点
✅ 优点 | ❌ 缺点 |
---|---|
结构灵活,统一管理 | 容器与单元职责不够明确(都实现统一接口) |
客户端统一使用接口 | 修改会影响所有子类 |
支持递归组合 | 对于简单结构显得复杂 |
🐍 Python 示例:文件系统结构(组合 + 递归)
1️⃣ 抽象组件(统一接口)
from abc import ABC, abstractmethod# 抽象组件(无论是文件还是文件夹,都要实现 show 方法)
class FileSystemComponent(ABC):def __init__(self, name):self.name = name@abstractmethoddef show(self, indent=0):"""显示内容,子类必须实现"""pass
2️⃣ 叶子节点:文件(不可再包含)
class File(FileSystemComponent):def show(self, indent=0):# 打印文件名,加上缩进表示层级print(" " * indent + f"📄 文件: {self.name}")
3️⃣ 容器节点:文件夹(可嵌套)
class Folder(FileSystemComponent):def __init__(self, name):super().__init__(name)self.children = [] # 保存子文件或子文件夹def add(self, component: FileSystemComponent):# 向文件夹添加一个子组件(可能是 File 或 Folder)self.children.append(component)def show(self, indent=0):# 先打印当前文件夹名称(缩进代表层级)print(" " * indent + f"📁 文件夹: {self.name}")# 遍历所有子项,并递归调用每个子项的 show()for child in self.children:child.show(indent + 2) # 缩进增加两格,表示进入下一层
🧠 一句话总结递归含义:
✅ 文件夹是自包含的容器,调用自己的 .show() 方法时,会再去调用所有子组件的 .show(),直到叶子节点(文件)为止。
4️⃣ 客户端使用
# 创建文件夹结构:根目录 → 文档 & 图片文件夹
root = Folder("根目录")
doc = Folder("文档")
img = Folder("图片")# 添加文件到文档文件夹
doc.add(File("简历.docx"))
doc.add(File("合同.pdf"))# 添加文件到图片文件夹
img.add(File("照片1.jpg"))
img.add(File("照片2.png"))# 构建总结构
root.add(doc) # 根目录包含文档
root.add(img) # 根目录包含图片
root.add(File("readme.txt")) # 根目录包含一个独立文件# 展示结构(递归触发入口)
root.show()
✅ 输出结果:
📁 文件夹: 根目录📁 文件夹: 文档📄 文件: 简历.docx📄 文件: 合同.pdf📁 文件夹: 图片📄 文件: 照片1.jpg📄 文件: 照片2.png📄 文件: readme.txt
✅ 说明:对文件和文件夹使用同样的 .show()
方法,自动递归展示结构。
🧭 清晰完整类图(Mermaid)
🧠 应用场景
应用领域 | 示例 |
---|---|
文件系统 | 文件和目录统一管理 |
组织架构 | 员工和部门层级 |
UI 组件 | 按钮、容器、面板等统一渲染 |
数学表达式树 | 节点可以是值,也可以是组合表达式 |
🧠 总结口诀
✅ 组合模式:把单个和一群统一看待,一起操作不区分
使用场景:整体-部分结构 + 客户端无需区分子节点/组合节点
是否想要我补充一个 UI 控件树 或 公司组织树 的组合模式版本?
📁📄📂 或者我帮你把这一套生成成图文学习卡片?继续深入?