@
netabare 我这样整体地描述该模式,看看是否命中了你的疑惑,因为我觉得可能你对这个模式的运转方式理解错了。
首先有一组固定类型的 object ,每个 object 内有多种类型的 element ,然后有多个 visitor 可以处理这组 object 。
每个 visitor 定义了一种将这组 object 输出为一种形式的业务逻辑,那么多个 visitor 分别代表可以输出不同形式的业务逻辑,visitor 之间是互相独立的。每种 element 需要对应一个 visitor 的 visitXXXElement 方法的实现。该方法的调用通过 element.accept 来做 dispatch ,这样就避免了业务侧用 switch case 做模式匹配,仅需 iterate elements 的 accept 方法即可完成调用。
其中关于 accept 的返回值,如果对这组 object 进行 visit 的结果是顺序的列表,自然可以直接将返回值简单地 map 为顺序列表。但如果 visit 的结果是其他复杂的类型,这部分业务逻辑必须由 visitor 在内部暂留状态,在整体 visit 结束后通过注入 end 的方法返回。这完全取决于要处理的业务,这部分不是该模式的核心。
其中关于 iterate elements ,这部分甚至也可以做到 visitor 的基类中,取决于 elements 的顺序如何产生,是统一的还是无关的。这部分不是该模式的核心。
举个例子,把一种 tree 输出为 json 、xml 、table 不同格式的业务。这里 tree 就是 object ,各种 tree node 就是 element ,json xml table 各需要一种 visitor. 其中对于 xml 如果选择用 element 嵌套的格式来表示输出形式,那么自然不可能直接由 accept 返回,因为整体结果是个 xml root element.