Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java的访问者模式_Java_Design Patterns_Visitor Pattern - Fatal编程技术网

Java的访问者模式

Java的访问者模式,java,design-patterns,visitor-pattern,Java,Design Patterns,Visitor Pattern,我有一个关于访客模式的问题!假设我有一个数据结构类,在它里面我有一个与类2的has-a关系。Class2具有特定的类层次结构,大约有10个类 我需要创建Class1实例的列表,并根据Class2的类型为Visitor.visit(Class1)发送请求。我不能对类2使用迭代,因为我需要来自类1上下文的变量 现在我在考虑接受Class1对象的dispatcher,然后在这个类的基础上检查class2的类型并调用一些东西 visitor.visitClass2Type1(Class1对象) 但在这种

我有一个关于访客模式的问题!假设我有一个数据结构类,在它里面我有一个与类2的has-a关系。Class2具有特定的类层次结构,大约有10个类

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

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

visitor.visitClass2Type1(Class1对象)

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

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

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


当您有一个嵌套了多个级别的对象关系时,您可以添加一个类似的leveContext()方法,并在visitor类中保留一个上下文堆栈。

我认为您的visitor.visit方法应该类似于visitor.visit(Class2,Class1),其中visitor类将为每种类型的Class2实现visit方法

所以您可以实现visit(Class2-1,Class1),visit(Class2-2,Class1)…visit(Class2-10,Class1)

我认为,通过这种方式,您将能够访问visit方法中的Class1对象信息,并且由于visit方法调用将动态决定,所以无论您的Class2列表中有什么内容

有关更多信息,请参阅wiki页面:

把菲利普建议的东西再向前推进一步,试试这个

给定的类小部件是父类,类特性是子层次结构的基本类型

简单用法:

// 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);
小部件(父类):

要素类层次结构:

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;
   }

}

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

如果我以错误的方式解释了您的问题,请告诉我;)
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;
   }

}