2011-01-18 9 views
0

訪問者パターンの実装では、以下のようなインターフェイスがあります(インターフェイス自体が間違っていると思われる場合は自由に教えてください)、訪問したすべてのアイテムのリストを追跡する責任は誰にありますか?訪問者か訪問者か?具体的には、トラッカーは、同じアイテムが2回訪問されていないことを確認する責任も負う必要があります(訪問しているグラフに循環参照が含まれている場合)。訪問者パターンアイテムトラッカー

/// <summary> 
/// Defines a type that may accept visitors. 
/// </summary> 
/// <typeparam name="T"></typeparam> 
public interface IVisitable<T> 
{ 
    // Methods 
    void Accept(T instance, IVisitor<T> visitor); 
} 

/// <summary> 
/// Defines a type that visits objects. 
/// </summary> 
/// <typeparam name="T"></typeparam> 
public interface IVisitor<T> 
{ 
    // Methods 
    void Visit(IVisitable<T> visitable); 

    // Properties 
    bool HasCompleted { get; } 
} 

答えて

3

訪問者は、訪問したすべてのアイテムを追跡する必要があります。訪問者は訪問先を常に知っているIVisitableと比較して、訪問先は常に把握しています。

他の任意の溶液はカップリングを増加させる。あなたのインターフェイスとして

彼らはこのように見えるように、私はそれらを変更します

public interface IVisitable<T> 
{ 
    void Accept(IVisitor<T> visitor); 
} 

public interface IVisitor<T> 
{ 
    bool Visit(T item); 
} 

をこれは、複数回同じ項目を処理していない可能性がある場合、訪問者が訪問した項目のリストを保持する必要があることを意味します。

public class MyVisitor : IVisitor<TheItem> 
{ 
    private List<TheItem> _visitedItems = new List<TheItem>(); 

    public bool Visit(TheItem item) 
    { 
     if (_visitedItems.Contains(item)) return true; 
     _visitedItems.Add(item); 

     //process here. Return false when iteration should be stopped. 
    } 
} 

public class MyItems : IVisitable<TheItem> 
{ 

    public void Accept(IVisitor<TheItem> visitor) 
    { 
     foreach (var item in items) 
     { 
      if (!visitor.Visit(item)) 
       break; 
     } 
    } 
} 

アップデート2

IEnumerable(イテレータ)は、実際に訪問の進化でありますまたはパターン。違いは、訪問したクラスの内側から外側にループを移動することです。あなたがリストを作成することができます

アップデート3

List<MyItem> items = new List<MyItem>();をしてforeachステートメントを使用して、それを繰り返す(IEnumerable<T>インタフェースを使用する):

foreach (var item in items) 
{ 
    //do anything here. use `break` to exit loop. 
} 

と同じことだ:

var enumerator = items.GetEnumerator(); 
while (enumerator.MoveNext()) 
{ 
    Console.WriteLine("The item: " + enumerator.Current); 
} 
+0

私は上のインターフェイスを与えて、それを行う方法がわかりません。 IVisitorに訪問(Tインスタンス)メソッドがあり、訪問(IVisitable 訪問可能)ではありませんか?または、インスタンスと訪問可能の両方を取る必要がありますか? – Jeff

+0

私の更新をチェックしてください。 – jgauffin

+0

しかし訪問者だけがアイテムのリストを含んでいれば、反復を止めるべきであることを訪問者は知ることができますか?私はすべてのノードが訪問されるまで、グラフ全体を見たいと思う。 – Jeff

関連する問題