2

我有一个关于访客模式的问题!想象一下,我有数据结构类,并且在其中我与 Class2 有一个 has-a 关系。Class2 具有特定的类层次结构,大约有 10 个类。

我需要根据 Class2 的类型迭代 Class1 实例列表并调度 Visitor.visit(Class1) 的请求。我不能对 class2 使用迭代,因为我需要来自 class1 上下文的变量。

现在我正在考虑接受 Class1 对象的调度程序,然后在这个类的基础上检查 class2 的类型并调用一些东西

visitor.visitClass2Type1(Class1 对象)

但在这种情况下,我失去了访问者模式的相同签名......

另一个问题是如何在访问者模式的上下文中注入变量。就像我遍历树结构一样,我想保留上一级的父变量以在较低级别执行某些操作。

4

3 回答 3

4

您可以向访问者类添加一个 setContext() 方法,该方法告诉访问者需要在哪个上下文中解释以下对象。

当您有一个嵌套多个级别的对象关系时,您可以添加一个模拟 leaveContext() 方法并在您的访问者类中保留一堆上下文。

于 2012-08-29T14:55:47.367 回答
2

采取菲利普建议的更进一步,试试这个。

给定类 Widget 是父类,类 Feature 是子层次结构的基类型

简单用法:

// widget will have an instance of a Feature subclass from args or config, etc
Widget theWidget = new Widget(args);

// create and configure visitor
Visitor theVisitor = new Visitor();
theVisitor.prop1 = x; 
theVisitor.prop2 = y;
theVisitor.prop3 = z;

theWidget.visit(theVisitor);

小部件(父类):

class Widget 
{
   Feature _childFeature;

   void visit(Visitor visitor)
   {
      visitor.beginAccept(this);
      childFeature.visit(visitor);            
      visitor.endAccept();
   }

}

要素类层次结构:

abstract class Feature
{
   abstract void visit(Visitor visitor);
}

class Sunroof extends Feature
{
   void visit(Visitor visitor)
   {
      visitor.accept(this);
   }
}

class BulletProof extends Feature
{
   void visit(Visitor visitor)
   {
      visitor.accept(this);
   }
}

class GoldPlated extends Feature
{
   void visit(Visitor visitor)
   {
      visitor.accept(this);
   }
}

一个同时使用父母和孩子的具体访问者:

class ExampleVisitor extends Visitor
{

   private _widgetInProcess;


   void beginAccept(Widget w)
   {
      _widgetInProcess = w;
   }

   void accept(Sunroof feature)
   {
      // do work based on both _widgetInProcess and type-specific feature
   }

   void accept(BulletProof feature)
   {
      // do work based on both _widgetInProcess and type-specific feature
   }

   void accept(GoldPlated feature)
   {
      // do work based on both _widgetInProcess and type-specific feature
   }

   void endAccept()
   {
      _widgetInProcess = null;
   }

}

您还可以可视化树模型用例,以及在beginAccept您推送到堆栈的位置,各种accept方法查看堆栈以获取其父上下文,并endAccept从堆栈中弹出。这可以让您递归处理树,同时始终可以访问父链。

于 2012-08-30T13:13:43.323 回答
2

我认为您的 Visitor.visit 方法应该类似于 Visitor.visit(Class2, Class1) 您的访问者类将为每种类型的 Class2 实现访问方法。

所以可以实现vi​​sit(Class2-1, Class1), visit(Class2-2,Class1)...visit(Class2-10,Class1)

我认为通过这种方式,您将能够访问访问方法中的 Class1 对象信息,并且访问方法调用将动态决定,因此您的 Class2 列表具有什么并不重要......

有关更多信息,您可以参考 wiki 页面: http ://en.wikipedia.org/wiki/Visitor_pattern

于 2012-08-29T15:16:11.567 回答