访问者模式的核心目标是将操作逻辑从元素对象中分离,元素仅实现accept方法调用访问者visit,访问者按类型实现对应处理逻辑,对象结构统一调度,从而实现行为与数据解耦。

访问者模式的核心目标就是把操作逻辑从元素对象中“拎出来”,让元素只管自己是什么、长什么样,而不管别人怎么处理它。这种剥离不是靠继承或硬编码,而是靠双向约定:元素主动“接受”访问者,访问者按类型“认出”元素并执行对应动作。
元素只需声明“我能被谁访问”
每个具体元素(比如 TextElement、ImageElement)不写打印、导出、统计等任何业务逻辑,只实现一个统一的 accept(Visitor v) 方法。这个方法唯一职责是:把自己作为参数,调用访问者的 visit(this)。
这样做的效果是:
- 元素类不再因新增功能而频繁修改,结构稳定
- 元素内部细节(如字段名、私有方法)仍可封装,不强制暴露
- 所有元素对外提供一致的接入点,便于统一遍历
访问者集中定义“我怎么处理各类元素”
访问者接口为每种具体元素类型声明一个 visit() 方法,例如:
- visit(TextElement e)
- visit(ImageElement e)
- visit(TableElement e)
具体访问者(如 ExportVisitor 或 ValidationVisitor)实现这些方法,在各自方法体内编写与该元素类型强相关的逻辑。同一份数据结构,换一个访问者,就能完成完全不同的任务。
对象结构负责“把人带进门”
ObjectStructure 不是简单的容器,而是协调者。它持有元素集合,并提供类似 acceptAll(Visitor v) 的方法——遍历所有元素,挨个调用它们的 accept(v)。
客户端只需:
- 构造好具体访问者(如 new PdfExportVisitor())
- 传给对象结构(structure.acceptAll(visitor))
后续所有 dispatch 和类型分发都自动完成,无需手动判断 instanceof 或一堆 if-else。
剥离之后带来的实际好处
操作行为真正从元素中解耦后,你会明显感受到:
- 加一个新功能(比如“生成缩略图”),只新增一个 ThumbnailVisitor 类,零改动现有元素代码
- 修改某类元素的处理逻辑(比如图片导出压缩率),只改 ExportVisitor.visit(ImageElement),不影响文本或表格
- 不同团队可以并行开发:前端组维护元素结构,算法组专注写各种 Visitor,接口对齐即可
不复杂但容易忽略:剥离的前提是元素类型相对固定。如果经常要新增元素种类(比如突然加个 VideoElement),就得同步更新所有访问者接口和实现——这时就要权衡是否仍适用该模式。

















