Java的访客模式

时间:2012-08-29 14:40:02

标签: java design-patterns visitor-pattern

我对访客模式有疑问!想象一下,我有数据结构类,在里面我有一个与Class2的关系。 Class2具有特定的类层次结构,大约有10个类。

我需要根据Class2的类型显示Class1实例列表和Visitor.visit(Class1)的调度请求。我不能在class2中使用迭代,因为我需要来自class1 context的变量。

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

visitor.visitClass2Type1(Class1对象)

但在这种情况下,我为访客模式松开了相同的签名......

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

3 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:2)

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

所以你可以实现访问(Class2-1,Class1),访问(Class2-2,Class1)...访问(Class2-10,Class1)

我认为通过这种方式,您将能够在访问方法中访问Class1对象信息,并且访问方法调用将动态决定,因此您的Class2列表无关紧要...

有关详细信息,请参阅维基页面: http://en.wikipedia.org/wiki/Visitor_pattern

答案 2 :(得分:2)

考虑到Philipp建议更进一步,试试这个。

给定类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);

Widget(父类):

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从堆栈中弹出。这可以允许您递归处理树,同时始终可以访问父链。