2009-07-09 54 views
1

我已经将XML文件解析为对象,其中每个对象与文件中的XML节点具有1:1的关系。这个对象树实现复合和Visitor设计模式为每杰里米米勒的以下博客条目:.NET C#访问者模式

http://codebetter.com/blogs/jeremy.miller/archive/2007/10/31/be-not-afraid-of-the-visitor-the-big-bad-composite-or-their-little-friend-double-dispatch.aspx

当我遍历对象树,我双调度它之前做一些处理AcceptVisitor()方法。作为处理某些对象的一部分,我在叶子/子对象上调用某些方法。现在,当我遍历子对象(作为正在进行的迭代的一部分)时,我不希望AcceptVisitor()加倍派遣任何东西。 (双派遣调用方法写文本到输出文件,我想避免文件中的重复文本。)我用一个标志实现了这个功能,但我对标志设计不满意。是否有修改版的Visitor模式来处理这种特殊情况?任何其他想法也是受欢迎的。

//Iterate object tree 
public void Iterate(Root root) 
{ 
     foreach (ILeaf child in root.ChildLeaves) 
     { 
      child.AcceptVisitor(this); 
     } 
} 

//This method in child object of type ILeaf gets called when Iterate() executes. 
public void AcceptVisitor(IVisitor visitor) 
{ 
     //Some child object implement ILeaf1 along with ILeaf 
     //I want to avoid any processing in AcceptVisitor() for objects of type ILeaf1 
     //once following loop executes. 
     //This means Iterate() should not process anyting in AcceptVisitor() for 
     //children of type ILeaf1. 
     IEnumerable<ILeaf1> children = this.ChildLeaves.OfType<ILeaf1>();   
     //Collection of action statements from child objects.   
     List<ActionStatement> statements = new List<ActionStatement>();   
     foreach (ILeaf1 s in children) 
     { 

      ActionStatement statement = s.Generate(); 
      statements.Add(statement);  
     } 
     //Output action statements to TextWriter 
     visitor.WriteStatements(statements); 
} 

//ILeaf1 object method 
public void AcceptVisitor(IVisitor visitor) 
{ 
     ActionStatement statement = new ActionStatement("Some Text"); 
     //Output action statement to TextWriter 
     visitor.WriteStatement(statement); 
} 
+2

为什么创建AcceptVisitor2()当然;) – zvolkov 2009-07-09 21:14:01

+0

添加一些代码来说明第二段,它的含义不清楚(至少对我来说)你的Accept()在做什么以及你希望它的行为如何。 – 2009-07-09 21:22:56

回答

1

我甚至没有看到您的AcceptVisitor(IVisitor)中正在使用访问者的位置。话虽如此,如果你想为异常情况提供不同的实现,你可以将两个委托传递给你的函数,一个用于测试特殊情况,一个用于描述你想为特殊情况做不同的处理。或者,使特殊情况除了正常情况外还实现另一个界面并测试(如果您的实现允许,您的描述/代码非常不清楚)。

1

没有必要在.NET C#中实现这个复杂的结构。我们可以实现访问者模式作为扩展方法。正如你们所知道的那样,通过使用扩展方法,你可以添加新的功能来分类,而无需访问或更改类。