【问题标题】:Visitor pattern where the visitors choose how to traverse访问者选择如何遍历的访问者模式
【发布时间】:2014-07-04 02:13:57
【问题描述】:

据我了解,在访问者模式的典型规范中,是被访问的对象决定如何遍历,一般来说,它们只支持一种遍历顺序。 (参见,例如,herehere。)

是否有相同用法的双重分派的名称,但访问者可以决定如何遍历对象层次结构?在我的应用程序中,一个非常异构的文档模型类型集合正在向访问者推送,例如导出操作。但是,说各种处理器(访问者)都应该按照广度优先顺序遍历似乎很僵硬。其中一些可能只关注模型的一个子集,或者可能需要按特定顺序处理模型的某些部分。

我担心以非标准方式使用访问者模式中的名称会混淆其他开发人员。我的建议有名称吗?

我还会问是否有理由不让访问者控制遍历,以防万一我缺少的通常的访问者公式中有一些智慧。如果可能相关,应用程序是 Java 语言。

【问题讨论】:

  • 你是怎么解决这个问题的? IMO 如果我们让访问者调用“接受”方法(即访问者选择遍历顺序),我们将完全违背模式,因为当我们更改“访问”对象的实现时,我们将需要完全更改访问者。
  • 我发现对于我的用例来说,遍历模型的各种函数之间几乎没有足够的重叠,因此抽象是没有帮助的。例如,一些函数需要在计算的各个阶段返回或另一种类型的数据,一些需要传递各种类型的多个参数,等等。
  • 我发现这篇文章很有趣tech.puredanger.com/2007/07/16/visitor。另请参阅 cmets 中关于将“访问逻辑”放在何处的讨论。

标签: design-patterns visitor-pattern double-dispatch


【解决方案1】:

为了保持设计清晰,您可以将遍历逻辑封装在一个迭代器中。访问者或被访问者可以使用迭代器来确定下一个要访问的节点。

在维基百科的访问者示例中,我们看到 Car 类控制访问顺序如下:

public void accept(ICarElementVisitor visitor) {    
    for(ICarElement elem : elements) {
        elem.accept(visitor);
    }
    visitor.visit(this);    
}

根据Iterator 模式,将遍历逻辑封装在从next() 方法返回ICarElementICarElementIterator 中很容易。

【讨论】:

  • 感谢您的回答。您能否详细说明或提供一些链接?
  • @JohnTortugo 我为你添加了更多细节。
  • @Fuhrmanator 答案中提到的遍历代码是否应该添加到Visitees的基类中?
  • @VK 我会把它放在对凝聚力有意义的地方。也就是说,如果遍历逻辑真的是结构的一部分,那么就把它放在那里。如果它是访问者特定功能的一部分(即遍历顺序取决于访问者提供的功能),则将其放入访问者中。
猜你喜欢
  • 2022-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
相关资源
最近更新 更多