如何在访客模式中传递“位置”信息?

时间:2009-02-09 22:04:51

标签: visitor-pattern

说我有这样的访客

class Visitor : IVisitor
{
     void Accept(Visitable v)
     {
         /// other code
         v.AChild.Visit(this);
         v.BChild.Visit(this);
     }
}

其中AChild和BChild可以是完全相同的类型,但访问代码需要区分它们(它需要在AChild上以不同于BChild的方式运行)。这样做的最佳方式是什么?

  • 在访问者中设置状态并在下次通话中进行检查
  • 将不同的访客传递给每个孩子
  • 其他?

对不起,我第一次向后退了(当前AcceptVisit)。它现在匹配the pattern as show in Wikipedia

所有访问方法都是这样的:

void Visit(IVisitor v) { v.Accept(this); }

3 个答案:

答案 0 :(得分:2)

您仍然从我认为传统上使用该模式的方式向后命名方法。可访问(或元素)通常具有accept方法,Visitor具有visitX方法。我将使用传统的命名方案来避免让自己感到困惑: - )

IMO最简单的方法是让您的访客界面上有多个方法,每种方法都有一种方法。如果孩子是相同的语言类型并不重要,如果他们在语义上不同,他们应该用不同的方法处理。

您还应该尝试使用有关Visitable结构的详细信息来避免污染Visitor实现。为了做到这一点,我将接受方法向上移动到Visitable接口,而不是在该接口上公开childA和childB。然后,Visitable的每个实现都可以决定访问者为每个孩子调用哪种方法。这将向访问者传达所有“位置”上下文,并为您提供一个漂亮,干净,分离的解决方案。

这是我正在思考的一个例子。我再次将方法名称交换回我习惯的方式。

interface Visitable {
  accept(Visitor v)
}

interface Visitor {
  visitA(Node a)
  visitB(Node b)
}

class Container implements Visitable {
  private Node childA
  private Node childB

  ...
  void accept(Visitor v) {
    v.visitA(childA)
    v.visitB(childB)
  }
}

现在您可以实现一个具有两种不同方法的访问者,一种用于处理A子女,另一种用于处理B子女。

答案 1 :(得分:0)

根据您的体系结构,您应该致电v.Visit(this),让您的Visitable实施确定如何使用AChildBChild

另外,请考虑AChildBChild可能应该是您的可访问实例的私有成员。

答案 2 :(得分:0)

根据原始海报a background question中的答案提供以下附加信息:

The visitor object is required to know the structure of the things it visits. That's OK, though. You're supposed to write specialized visit operations for each type of thing the visitor knows how to visit. This allows the visitor to decide how much it really wants to visit, and in what order.

我会回答:创建一个特殊的IVisitor类,可能叫做ABChildVisitor,它有一个Visit()方法,知道如何遍历AChild和BChild。