0

我已经看到了用于遍历AST的访问者模式。accept(visitor)要使用此模式,您需要在 AST 节点对象上添加一个方法。这个方法调用visitor.visit(self)它,反过来,“处理”节点以获得所需的结果(例如,AST 的漂亮打印版本)。

请注意,您通常必须修改节点本身才能添加方法。但是,如果您的 AST 使用内置对象怎么办。Ruby 的 Ripper 库将 AST 作为数组返回。我可以添加accept如下方法:

class Array
  def accept(visitor)
    visitor.visit(self)
  end
end

查看 Array的文档,目前没有accept方法,所以不会有冲突。但是,这对我来说并不完全正确,尤其是当我自己编写一个库时。我不想“污染”其他人可能依赖的内置对象。

不过,这并不是 Ruby 独有的,因为我可以在 C# 中添加一个扩展方法来做类似的事情。

我的问题是:我应该在这种情况下使用访问者模式,还是应该编写一个递归函数,只接受我正在处理的数据类型并返回我想要的答案?

4

1 回答 1

1

访问者模式是一种已知的规避重复问题的解决方案(这里的问题可能只适用于不提供多重调度的编程语言)。

正如您似乎知道的那样,很多时候人们希望清楚地将数据结构与人们可能想要用它做的事情区分开来。

通常,您有一个类层次结构(具有不同类型节点的树)。然而,在这种情况下,我没有看到这种情况发生。所以我想知道你为什么要首先使用访问者模式。创建将数组作为输入并对其进行处理的不同类不是更容易吗?

于 2011-03-07T14:15:06.237 回答