我对访客模式有疑问!想象一下,我有数据结构类,在里面我有一个与Class2的关系。 Class2具有特定的类层次结构,大约有10个类。
我需要根据Class2的类型显示Class1实例列表和Visitor.visit(Class1)的调度请求。我不能在class2中使用迭代,因为我需要来自class1 context的变量。
现在我正在考虑接受Class1对象的调度程序,然后在这个类的基础上检查class2的类型并调用一些东西
visitor.visitClass2Type1(Class1对象)
但在这种情况下,我为访客模式松开了相同的签名......
另一个问题我如何在访问者模式的上下文中注入变量。就像我遍历树结构一样,我想保留前一级别的父变量,以便在较低级别执行某些操作。
答案 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
从堆栈中弹出。这可以允许您递归处理树,同时始终可以访问父链。