2009-07-09 10 views
1

私はXMLファイルをオブジェクトに解析しました。各オブジェクトはファイル内のXMLノードと1対1の関係にあります。このオブジェクトツリーは、ジェレミー・ミラーの以下のブログエントリごとにコンポジットおよびビジターデザインパターンを実装しています:.NET C#Visitor Pattern

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()メソッドでは、いくつかの処理を行います。特定のオブジェクトの処理の一部として、私はleafs/childrenオブジェクトの特定のメソッドを呼び出します。さて、子オブジェクトを(私は進行中の反復の一部として)横断するとき、私は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()of course;)を作成しますか? – zvolkov

+0

2番目の段落を説明するコードを追加して、Accept()が何をしているのか不明瞭で、代わりに動作させる方法を示します。 –

+0

デザインパターンは心を腐らせる! – Eric

答えて

1

あなたのAcceptVisitor(IVisitor)でどこのユーザーが使用されているのかわかりません。つまり、例外の場合に別の実装が必要な場合は、2つのデリゲートを関数に渡すことができます.1つは特殊なケースをテストし、もう1つは特殊なケースに対して別のやり方を説明するものです。あるいは、特別なケースを通常のものに加えて別のインターフェースを実装させ、それをテストします(あなたの実装が許せば、あなたの記述/コードは非常に不明です)。

+0

サンプルコードを更新しました。 – rxm0203

1

.NET C#でこの複雑な構造を実装する必要はありません。拡張メソッドとして訪問者パターンを実装することができます。多くの人が知っているように、拡張メソッドを使用すると、クラスにアクセスしたり変更したりすることなく、クラスに新しい機能を追加できます。