组合模式和装饰器模式、责任链模式有什么区别?
简化版
组合模式关注树形结构,让叶子和容器一致处理;装饰器模式关注给对象动态增强功能;责任链模式关注请求沿处理链传递。组合是“部分-整体树”,装饰器是“包一层增强”,责任链是“一个请求按链路流转”。
详细版
三者区别:
| 模式 | 核心目的 | 典型结构 |
|---|---|---|
| 组合模式 | 统一处理叶子和组合对象 | 树 |
| 装饰器模式 | 动态叠加功能 | 包装链 |
| 责任链模式 | 多处理器依次处理请求 | 处理链 |
组合模式中,一个节点可以有多个子节点。
装饰器模式中,一个装饰器通常包装一个对象。
责任链模式中,一个处理器通常指向下一个处理器,请求沿链传播。
判断关键不是看有没有集合或引用,而是看设计意图。
完整版教学
一、组合模式看的是部分和整体
组合模式适合:
目录包含文件和子目录
部门包含员工和子部门
菜单包含菜单项和子菜单
它关注的是层级结构和一致处理。
客户端可以对单个节点和整棵树执行同一操作。
二、装饰器模式看的是功能增强
装饰器模式常见结构:
BufferedInputStream -> FileInputStream
它关注的是在不改变原对象接口的情况下增加能力。
装饰器通常包装一个组件,而不是管理一组子节点。
三、责任链模式看的是请求传递
责任链模式常见结构:
AuthHandler -> LogHandler -> BusinessHandler
请求从一个处理器传给下一个处理器。
每个处理器决定处理、拦截或继续传递。
它关注的是处理顺序和请求流转。
四、结构相似但语义不同
这几个模式都可能出现:
- 共同接口;
- 对象引用;
- 递归或链式调用。
但语义不同:
- 组合表示树;
- 装饰表示增强;
- 责任链表示流程。
面试时不能只看代码结构,要说出业务意图。
五、真实项目中可以组合使用
例如权限菜单:
- 菜单树用组合模式;
- 菜单渲染时用装饰器增加图标或权限标记;
- 请求访问菜单接口时用责任链做鉴权、日志、限流。
模式之间不是互斥关系。
六、常见误区与追问
三种模式的拓扑和目的不同。组合模式可形成1对多分叉树;装饰器通常是一层包一层的单链,目的是叠加能力;责任链沿处理器后继传递请求,可能在第3个节点短路。看到递归引用不能直接下结论,必须检查调用是聚合子节点、包裹组件还是传递请求。
| 检查维度 | 判定依据 |
|---|---|
| 组合 | 部分—整体树,统一处理 |
| 装饰器 / 责任链 | 功能叠加 / 请求传递 |
记忆钩子:组合向下“分叉”,装饰器向内“包裹”,责任链向后“传递”。
- 误区:链式结构都属于责任链。 装饰器也呈链状,但它通常每层都增强同一组件。
- 追问:组合与装饰器能一起用吗? 可以,树节点本身可被装饰以增加缓存、日志等能力。
- 误区:组合节点只调用一个子节点。 它通常遍历多个孩子并聚合结果,这是与单链结构的重要区别。
- 追问:责任链一定会执行全部节点吗? 不一定,可在某个处理器决定已处理后停止。
- 追问:最快的区分问题是什么? 问结构要表达整体、增强对象,还是寻找请求处理者。
七、加强记忆
组合、装饰器、责任链的区分抓住目的:组合处理树形部分-整体,装饰器动态增强对象,责任链让请求沿链处理。看到树和统一处理,优先想到组合模式。