質問

デコレータパターンについての私の以前の理解は、 WindowDecorator Window を継承し、オーバーライドされたメソッドで、 Window の上記メソッドの実装。次のようなもの:

public class Window
{
    public virtual void Open()
    {
        // Open the window
    }
}

public class LockableWindow : Window // Decorator
{
    public virtual void Open()
    {
        // Unlock the window
        base.Open();
    }
}

ただし、これは基本的に装飾をハードコードするので、継承の代わりに構成を使用するためにどのようにリファクタリングされますか?

役に立ちましたか?

解決

申し訳ありませんが、私のC#は少し(大丈夫、非常に)さびているので、いくつかの構文エラーがあるかもしれませんが、基本的な考え方は正しいです。

public interface IWindow
{
    void Open();
}

public class Window : IWindow
{
    public virtual void Open()
    {
        // Open the window
    }
}

public class LockableWindow : IWindow
{
    private IWindow _wrappedWindow;

    public LockableWindow(IWindow wrappedWindow)
    {
        _wrappedWindow = wrappedWindow;
    }

    public virtual void Open()
    {
        // TODO Unlock window if necessary
        _wrappedWindow.open();
    }
}

注目すべき重要な点は、新しい IWindow インターフェースです。それがポリモーフィズムを使い続けることができる理由です。

他のヒント

Decoratorパターンのポイントは、呼び出し元に対して透過的な方法で、何らかの機能(たとえば、ストリームへのバッファリングの追加)でオブジェクトを強化することです。最も効果的に使用するには、コードをリファクタリングせずに装飾された実装でスワップできるようにする必要があります。これは基本的に、継承階層を維持する必要があることを意味します。

実際の懸念、つまり「装飾をハードコードする」ことは何ですか?本当に意味?どのような問題を解決したいと思いますか?装飾はあまり適切なアプローチではない可能性があります...

LockableWindowに、装飾するWindow型のインスタンスを取るコンストラクターを定義させるだけです。プロパティを介して行うこともできます。

public class Window
{    
  public virtual void Open()    
  {        
   // Open the window    
  }
}

public class LockableWindow // Decorator
{    
  private Window window;

  public LockableWindow(Window w)
  {
     window = w;
  }      

  public virtual void Open()    
  {        
    // Unlock the window        
    window.Open();    
  }
}

デコレータパターンについての私の理解は、オブジェクトの機能の実行時の強化を可能にすることを意図しているということです。ウィキペディアの説明では、この目的のためにコンポーネントスタックに焦点を当てています。

私はC#をまったく話さないので、これは(明らかに)php-ishです。正しい考えは次のように思われます:

class image{

     function open(){ ... }

} //end of class

class decoratedImage extends image{

     private goodies=array(); //the alleged 'component stack'

     function addGoodie($item){
          $this->goodies[]=$item;
     }

     function open()}{

          parent::open();
          foreach ($this->goodies as $componentClassName){

               $component=new $componentClassName();
               $component->apply($this);

          }

     }

} //end of class

ああ、経験者の皆さん、切断について説明してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top