面试知识库
进阶

组合模式#

一句话答案#

将对象组织成树形结构,客户端统一处理叶子和容器节点,适合文件系统/菜单/组织架构等树形场景。

核心要点

适用: 树形结构(文件系统/菜单/组织架构)

核心: Component(抽象) → Leaf(叶子) / Composite(容器,含子Component列表)

客户端统一调用 component.operation(),不区分叶子和容器

面试回答(2分钟版)

组合模式的核心思想是将对象组织成树形结构,让客户端可以统一地处理叶子节点和容器节点,不需要区分当前操作的是单个对象还是对象的组合。结构上有三个角色:Component 是抽象基类定义统一接口,Leaf 是叶子节点没有子节点,Composite 是容器节点内部持有一个子 Component 列表。最典型的例子就是文件系统——文件和文件夹都是”文件系统节点”,双击文件夹递归展开、双击文件直接打开,对使用者来说操作方式是统一的。在 Java 中,组织架构树、菜单系统、评论的树形结构都可以用组合模式。实现时有两种方式:透明方式把 add/remove 等管理子节点的方法放在 Component 里,叶子节点调用时抛异常,好处是客户端完全不用区分类型;安全方式只在 Composite 里暴露管理方法,更安全但客户端需要做类型判断。实际中如果只是简单的递归遍历,不一定非要套组合模式,直接递归就够了。

追问与易错

追问方向:

  • “什么时候用?”→ 数据具有树形/层级结构且需要统一处理叶子和容器节点时:文件系统(文件/文件夹)、菜单系统(菜单项/子菜单)、组织架构(员工/部门)、评论树等
  • “Java IO 中有组合模式吗?”→ 不算严格的组合模式,但 File 类同时表示文件和目录,listFiles() 返回子 File 数组,具有组合模式的思想;IO 流更多体现的是装饰器模式
  • “透明方式和安全方式区别?”→ 透明方式把 add/remove 放在 Component 抽象层,叶子节点调用时抛异常,客户端完全不区分类型;安全方式只在 Composite 中暴露管理方法,更安全但客户端需要类型判断

易错点:

  • ❌ 组合模式就是组合对象——核心是统一处理叶子和容器
  • ❌ 所有树形结构都用组合——简单递归就够了