← 返回题目列表

迭代器模式和组合模式、访问者模式有什么区别?

高频 困难 第 13 / 25 题 更新于 2026/07/28
迭代器模式组合模式访问者模式

简化版

迭代器模式关注如何遍历对象集合;组合模式关注如何把对象组织成树形整体;访问者模式关注在不改数据结构的情况下新增操作。它们常一起出现,但解决的问题不同。

详细版

三者的核心区别是:

  • 组合模式:解决对象结构问题,把叶子和容器统一成树。
  • 迭代器模式:解决遍历访问问题,隐藏集合或树的内部遍历细节。
  • 访问者模式:解决操作扩展问题,把作用在节点上的操作从节点类中分离出来。

例如文件系统:

  • 组合模式表示文件夹和文件的树形结构。
  • 迭代器模式遍历所有文件节点。
  • 访问者模式统计大小、生成索引、扫描病毒等操作。

完整版教学

一、迭代器模式关注遍历

迭代器模式的核心问题是:如何逐个访问元素,同时不暴露内部结构。

它关心:

  • 从哪里开始。
  • 是否还有下一个。
  • 下一个是谁。
  • 遍历顺序如何封装。

它不负责定义树形结构,也不负责新增业务操作。

二、组合模式关注结构

组合模式的核心问题是:如何让单个对象和组合对象具有一致接口。

例如文件和文件夹:

  • 文件是叶子节点。
  • 文件夹是容器节点。
  • 客户端可以统一调用 display()size()

组合模式负责把对象组织成整体和部分的层次结构。

三、访问者模式关注操作扩展

访问者模式的核心问题是:数据结构稳定,但操作经常增加。

例如语法树节点类型比较稳定,但要新增:

  • 类型检查。
  • 代码生成。
  • 格式化。
  • 复杂度分析。

访问者可以把这些操作放到独立类中,而不是不断修改节点类。

四、三者如何配合

在树形结构中,它们经常配合使用。

例如菜单系统:

  1. 用组合模式组织菜单和菜单项。
  2. 用迭代器模式遍历整棵菜单树。
  3. 用访问者模式对每个节点执行权限检查、导出、统计等操作。

这样结构、遍历、操作各自独立。

五、为什么容易混淆

它们都经常出现在集合或树结构里,所以容易混在一起。

判断时要看主要矛盾:

  • 如果问题是“整体和部分如何统一”,优先看组合模式。
  • 如果问题是“如何隐藏遍历细节”,优先看迭代器模式。
  • 如果问题是“如何在不改节点类的情况下增加操作”,优先看访问者模式。

六、面试回答建议

可以这样答:

迭代器模式解决遍历,组合模式解决树形结构,访问者模式解决操作扩展。它们可以配合使用,比如文件系统用组合模式建树,用迭代器遍历节点,用访问者统计大小或生成报表。

这个回答既区分了目的,也给了实际组合场景。

七、常见误区与追问

三种模式经常一起出现在树结构中,却关注不同问题。组合模式组织 N 个节点的部分—整体关系;迭代器决定按什么顺序访问;访问者把对节点类型的操作集中起来。比如文件树用 Composite 建模、Iterator 做深度优先、Visitor 计算权限报告。

检查维度判定依据
组合 / 迭代器组织树 / 封装遍历游标
访问者在稳定节点结构上扩展操作
Composite(结构) -> Iterator(顺序) -> Visitor(操作)

记忆钩子:组合回答“长什么样”,迭代器回答“怎么走”,访问者回答“走到后做什么”。

  • 误区:使用组合模式后不需要迭代器。 组合提供递归结构,但客户端仍可能需要独立遍历策略。
  • 追问:访问者为什么不等于迭代器回调? 访问者利用双分派按具体节点类型执行不同操作。
  • 误区:迭代器负责修改节点业务。 它主要控制访问顺序,业务操作应由客户端或访问者完成。
  • 追问:三者能否组合? 可以,而且树形对象处理中非常常见。
  • 追问:节点类型频繁变化时 Visitor 合适吗? 不太合适,每新增节点类型都要修改访问者接口和实现。

八、加强记忆

这三个模式可以记成“结构、走法、操作”:组合模式管结构,迭代器模式管走法,访问者模式管对节点做什么。看清问题落在哪一层,就不容易混淆。