5

どちらの手法を使用することにも大きなメリットはありますか?バリエーションがある場合、私が意味するビジターパターンはこれです:http://en.wikipedia.org/wiki/Visitor_pattern

そして、以下は同じ効果を達成するためにデリゲートを使用する例です(少なくとも私はそれが同じだと思います)

ネストされた要素のコレクションがあるとします。学校には、学生を含む学部が含まれます

ビジターパターンを使用して各コレクションアイテムで何かを実行する代わりに、単純なコールバックを使用してみませんか(C#のアクションデリゲート)

このようなことを言う

class Department
{
    List Students;
}

class School
{
    List Departments;

    VisitStudents(Action<Student> actionDelegate)
    {
        foreach(var dep in this.Departments)
        {
            foreach(var stu in dep.Students)
            {
                actionDelegate(stu);
            }
        }
    }
}

School A = new School();
...//populate collections

A.Visit((student)=> { ...Do Something with student... });

*複数のパラメータを受け入れるデリゲートを使用したEDITの例

学生と学部の両方に合格したいとします。次のようにアクション定義を変更できます。アクション

class School
{
    List Departments;

    VisitStudents(Action<Student, Department> actionDelegate, Action<Department> d2)
    {
        foreach(var dep in this.Departments)
        {
            d2(dep); //This performs a different process.
            //Using Visitor pattern would avoid having to keep adding new delegates.
            //This looks like the main benefit so far 
            foreach(var stu in dep.Students)
            {
                actionDelegate(stu, dep);
            }
        }
    }
}
4

2 に答える 2

9

訪問者パターンは通常、複数のタイプの訪問者がいる場合に使用されます。タイプ ( Student) は 1 つしかないため、ビジター パターンは実際には必要なく、デリゲート インスタンスを渡すだけで済みます。

Departments とs の両方にアクセスしたいとしますStudent。次に、訪問者は次のようになります。

interface ISchoolVisitor
{
    void Visit(Department department);
    void Visit(Student student);
}

もちろん、ここでデリゲートを使用することもできますが、複数のデリゲート インスタンスを渡すのは面倒です。

于 2012-12-07T22:45:40.630 に答える
4

ビジター パターンは、ツリーなどのネストされた構造内のノードがその子の具象型を認識していない場合に便利です。次に、ビジターを使用して、各子オブジェクトの実際の型に基づいて動作をディスパッチします。

Departmentsあなたの例では、学校は、子コレクションを持つ子コレクションがあることを知っていますStudent

の別の子要素を含めるように例を拡張するとSchool、コードは次のようになります。

public abstract class Manageable
{
    abstract void Accept(IManagebleVisitor visitor);
}

public interface IManageableVisitor
{
    void Visit(Department d);
    void Visit(Building b);
}

public class Department : Manageable { ... }
public class Building : Manageable { ... }

Schoolクラスは次のようになります。

public class School
{
    private List<Manageable> manageables;
    public void Accept(IManageableVisitor visitor)
    {
        foreach(var m in this.manageables)
        {
            m.Accept(visitor);
        }
    }
}

の具体的なサブクラスごとにデリゲートを渡す必要があるため、ここではデリゲート アプローチは機能しません。Manageable新しいサブクラスを階層に追加するには、School.Accpetメソッドを変更する必要があります。

于 2012-12-07T22:50:45.917 に答える