3

簡単に言えば、デコレータパターンを理解しています。あるクラスが別のクラスをラップするという考え方で、デコレータメソッドは、装飾されたオブジェクトで同じメソッドを呼び出す前および/または後に他のコードを実行したいと考えています。

しかし、望ましくない副作用があるため、decoratedメソッドを単純に呼び出すことができない状況に遭遇しました。しかし、私はその装飾されたメソッドの多くを実行したいと思っています。

したがって、decoratedメソッドを複数のメソッドに分割する必要があると思います。次に、デコレータでそれらのいくつかを呼び出し、装飾コードを実行してから、他のいくつかを呼び出すことができます。不要な副作用を見逃します。

ただし、ポリモーフィズムを維持するためには、decoratedオブジェクトとdecoratorオブジェクトが実装するインターフェイスにこれらのメソッドを追加することを意味します。これは望ましくありません。それらは公開されるべきではなく、それは事実上、装飾されたクラスがそれがどのように装飾されるかについての知識を持っていることを意味します。

テンプレートパターンの方がおそらくより適切であると思います。抽象基本クラスがそれぞれの小さなメソッドを順番に呼び出し、「デコレータ」が関心のあるメソッドの代替実装を提供するだけです。しかし、これは正確には「継承よりも構成」ではないので、何をお勧めしますか?

4

2 に答える 2

2

テンプレートがシナリオに最も適しているように聞こえます。必要のないときは構成を強制しません...この会話は、「...このルールの例外:継承を使用する必要がある場合、つまり代替可能性をモデル化する必要がある場合」と最もよく述べています。

于 2010-01-18T17:16:01.223 に答える
1

APIがコマンドクエリ分離に違反しているように思われるため、APIを再設計するのが最善の方法です。

ただし、私が間違っているか、再設計が不可能な場合は、インターフェイスを変更せずに、装飾されたクラスのメソッドを2つのメソッドに分割できます。

public interface IMyInterface
{
    Foo GetFoo(Bar bar);
}

public class MyClass : IMyInterface
{
    public Foo GetFoo(Bar bar)
    {
        this.DoSomethingWithSideEffects(bar);
        return this.DoSomethingToGetFoo(bar);
    }

    public Foo DoSomethingToGetFoo(Bar bar)
    {
        // ...
    }

    public void DoSomethingWithSideEffects(Bar bar)
    {
        // ...
    }
}

public class MyDecorator : IMyInterface
{
    private readonly MyClass mc;

    public MyDecorator(MyClass mc)
    {
        // put Null Guard here...
        this.mc = mc;
    }

    public Foo GetFoo(Bar bar)
    {
        return this.mc.DoSomethingToGetFoo(bar);
    }
}

MyDecoratorがIMyInterfaceではなくMyClassを装飾していることに注意してください。

于 2010-01-18T18:41:48.677 に答える