2

オープンソース プロジェクトAfterthoughtをリファクタリングして、より直感的に使用できるようにすることを検討しています。基本的な考え方は、Afterthought で修正を作成する開発者は、特定の .NET 型を修正し、型自体と、プロパティ、メソッド、イベント、コンストラクターなどのリスト (ツリー) を変更する機会が与えられるというものです。私が内部で使用している API Microsoft CCI Metadataは、API でビジター パターンを広範に使用しているため、以下のように、Afterthought で同様のアプローチを採用しました。

public override void Amend()
{
    // Amend the type here, add properties, add methods, etc.
}

public override void Amend<TProperty>(Property<TProperty> property)
{
    // Amend properties here
    if (property.Name == "Result")
    {
        // Modify Result property
    }
}

public override void Amend(Method method)
{
    // Amend methods here
    if (method.Name == "Add")
    {
        // Modify Add method
        method.Implement(TInstance instance, int x, int y) => x + y);
    }
}

しかし、ビジター パターンは実際には、対象の問題 (クラス ライブラリのインストルメント化など) を解決するコードを、ツリーの側面に焦点を当てた一連の異なるメソッドに再配布することになることを発見しました。これは、API を作成する開発者にとっては簡単に実装できますが、消費者はやや不自然な方法でコードを展開する必要があります。ツリーをリストとして公開し、LINQ スタイルのアプローチを活用することよりも、vistor-pattern にはどのような利点があるのでしょうか。

私が検討している代替構文は次のとおりです。

public override void Amend()
{
    // Do everything here, possibly calling methods just to organize the code

    // Modify Add method
    Methods.Named("Add").WithParams<int, int>()
        .Implement((instance, x, y) => x + y);
}

したがって、この場合、Amendment の作成者は、メソッドをオーバーライドする代わりに、fluent/LINQ API を公開するリストを操作することで、すべてのコードを 1 か所 (または選択した場所) に書き込むことができます。明らかに、このアプローチはパフォーマンスがわずかに低下します (反復が増えるなど) が、これ以外にマイナス面はありますか?

4

1 に答える 1

3

Visitor パターンを使用すると、訪問した要素の型をテストするiforswitchステートメントの作成を回避できます。これらのステートメントを避けることは、一般的に良い習慣と考えられています。実装する操作が、アクセス可能な要素のさまざまなタイプを区別しない場合は、そうです。ビジター パターンは、他のアプローチよりも優れた利点をもたらしません。

問題は、ビジター パターンの理解にある可能性があります。これは、主に、この機能を提供しない言語での二重ディスパッチの実装、または (これは C# の場合です) 二重ディスパッチの使用がかなりのパフォーマンスの問題をもたらす言語での実装に関するものです。それは木の横断についてではありません。階層構造を形成しないクラスにも使用できます。GoF book によると、トラバース アルゴリズムは、訪問者自体、訪問された要素、またはクライアントのいずれかによって実装される可能性があります。

編集:あなたの質問をもう一度注意深く読みました。あなたのアプローチは、たとえば、ビジターがクラスではなくラムダ関数のセットであるビジターパターンの代替実装であると思います。

于 2011-05-28T14:28:28.777 に答える