Alrite,我会直接跳到代码:
public interface Visitor {
public void visitInventory();
public void visitMaxCount();
public void visitCountry();
public void visitSomethingElse();
public void complete();
//the idea of this visitor is that when a validator would visit it, it would validate data
//when a persister visits it, it would persist data, etc, etc.
// not sure if I making sense here...
}
public interface Visitable {
public void accept(Visitor visitor);
}
Run Code Online (Sandbox Code Playgroud)
这是一个基础实现:
public class StoreValidator implements Visitor {
private List <ValidationError> storeValidationErrors = new ArrayList<ValidationError>(); …Run Code Online (Sandbox Code Playgroud) 如果我们想要将枚举(包含在域层中)重构为多态类,那么使用"简单"抽象方法可能是一个坏主意,如果我们要重构的所有switch和if语句都在其他层内(如业务或表示层),因为我们最终可能会在域层内引用这些层:
public abstract class MyRefactoredEnum
{
public abstract void DoSomething(IBusinnessObject aBizObject); //dependency to the biz. layer
public abstract MvcHtmlString GetImgTag(); //dependency to presentation layer
}
Run Code Online (Sandbox Code Playgroud)
(在上面的例子中,我们也可以有一个"交叉引用"问题)
我发现访问者模式(http://en.wikipedia.org/wiki/Visitor_pattern)是这个问题的有效解决方案:在域层我们只定义了MyRefactoredEnum.IVisitor接口,所有其他层都可以实施自己的访客.
唯一的问题是:当我们修改MyRefactoredEnum.IVisitor接口时(例如,因为我们添加了另一个MyRefactoredEnum的子类),我们必须修改并重新编译引用域模型的所有项目和解决方案.我们可以使用反射来解决问题(http://surguy.net/articles/visitor-with-reflection.xml),但它可能很慢......
重构枚举是否有更好的模式?
PS:对不起我糟糕的英语:)
深度优先搜索似乎能够执行与访客设计模式相似的功能。访问者允许您定义一些数据结构并根据需要在这些结构上添加操作(以多个访问者的形式),而无需修改结构本身。维基百科上提供了访客模式的描述。如果我们在数据结构上进行深度优先搜索(或其他任何图形搜索算法,例如广度优先搜索),并且每次找到该结构的元素,我们都会运行所需的操作,那么这似乎执行与访客。例如,考虑一棵树。即使树的某些节点具有不同的类型,我们在执行DFS时仍然可以检查节点类型,然后根据节点类型执行不同的操作。
我有一个包含许多类的复合类结构。由于许多不同的原因(验证、克隆、导出为 xml 等),需要遍历此结构,因此编写使用访问者模式是有意义的。鉴于以下类结构
class Owner
{
public string Name { get; set; }
public List<Owned> Liked { get; private set; }
public List<Owned> Disliked { get; private set; }
public Owner()
{
this.Liked = new List<Owned>();
this.Disliked = new List<Owned>();
}
}
class Owned
{
public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
如果我想生成这样的 XML 应该如何实现这样的访问者模式
<owner>
<name>Owner 1</name>
<likedThings>
<owned>
<name>Liked thing 1</name>
</owned>
<owned>
<name>Liked thing 2</name>
</owned>
</likedThings>
<dislikedThings>
<owned>
<name>Disliked thing 1</name>
</owned>
<owned>
<name>Disliked thing …Run Code Online (Sandbox Code Playgroud) 我正在做一个关于访问者设计模式的演示,我了解它是如何工作的,但是我还没有找到“定义的”优点和缺点,而且我不想自己推测优点或缺点,因为我可以设置虚假信息。
我试图用C++ 实现Oppen的算法.
此算法中的基本例程(打印和扫描)在令牌类型上进行调度.使用访问者模式实现此调度似乎很自然.问题是:例程是嵌套的,print()的参数在scan()期间在堆栈中排队.为了避免任何内存问题,我想使用智能指针来完成任务.
所以我的实现看起来像这样:
class Text;
class Line;
class Open;
class Close;
class Visitor {
/* Define virtual visit functions for concrete doc nodes:
*/
public:
virtual void visit(const Text&) = 0;
virtual void visit(const Line&) = 0;
virtual void visit(const Open&) = 0;
virtual void visit(const Close&) = 0;
};
class DocToken
{
protected:
explicit DocToken() {}
friend class Visitor;
public:
virtual void accept(Visitor * visitor) const = 0;
};
class Text : public DocToken {
public: …Run Code Online (Sandbox Code Playgroud) 这个 Babel 插件:
module.exports = function(){
return {
visitor:{
Program:{
enter(){ console.log('Enter') },
exit(){ console.log('Exit') }
}
},
pre(){ console.log('Pre') },
post(){ console.log('Post') }
}
}
Run Code Online (Sandbox Code Playgroud)
为任何 javascript 文件生成以下输出:
Pre
Enter
Exit
Post
Run Code Online (Sandbox Code Playgroud)
pre()Program.enter()在 之前和post()之后调用Program.exit()。
如果我想在 AST 遍历的开始/结束时运行一些代码,有什么理由我应该将该代码放在pre/post而不是Program.enter/中Program.exit?
有什么区别吗?
有人会解释这些是指什么?
MemberReference, TypeReference, ExternType, Override, NestedType,
PInvokeInfo, SecurityDeclaration and CustomAttribute and MarshalSpec
Run Code Online (Sandbox Code Playgroud)
如果你能举例说明,那将是理想的.
我正在尝试写一个访客模式Mono.Cecil.
我的出发点如下:
- 我有一个方法,转换,我重载,根据传入的参数类型不同(参见transform(A a1,A a2)和transform(A a1,B b))在下面的例子中)
- 所有这些参数都实现了相同的接口X.
我想在所有实现X接口的各种对象上应用该转换方法.
我想到的是实现变换(X x1,X x2),它在应用变换的相关变量之前检查每个对象的实例.
虽然它有效但代码看起来很难看,我也担心评估这些各种instanceof和cast的性能开销.这是我用Java做的最好的转换,还是有更优雅和/或更有效的方法来实现相同的行为?
以下是印刷BA的一个简单的工作示例.我正在寻找有关如何改进该代码的示例.在我的真实代码中,我自然有更多的'transform'实现,而且没有一个像下面那样简单.
public class A implements X {
}
public class B implements X {
}
interface X {
}
public A transform(A a1, A a2) {
System.out.print("A");
return a2;
}
public A transform(A a1, B b) {
System.out.print("B");
return a1;
}
// Isn't there something better than the code below???
public X transform(X x1, X x2) {
if ((x1 instanceof A) && (x2 instanceof A)) { …Run Code Online (Sandbox Code Playgroud) java reflection overloading multiple-dispatch visitor-pattern
我想像这样在 C++ 中实现访问者模式:
class Visitor{
public:
virtual ~Visitor();
virtual void visit(C & t)=0;
};
class V : public Visitor{
public:
void visit(C &c);
};
class C{
public:
void accept(Visitor &v){ v.visit(*this); }
};
Run Code Online (Sandbox Code Playgroud)
但是编译器抱怨大约 2 个语法错误:未知标识符 C 和访问者。问题出在哪儿?
visitor-pattern ×10
c# ×3
java ×3
c++ ×2
babel-plugin ×1
babeljs ×1
enums ×1
mono ×1
mono.cecil ×1
node.js ×1
oop ×1
overloading ×1
polymorphism ×1
reflection ×1
search ×1
tree ×1