0

デコレータパターンについての私の以前の理解は、で継承Windowし、オーバーライドされたメソッドで、上記のメソッドの実装をWindowDecorator呼び出す前にいくつかの追加の作業を行うことでした。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();
    }
}

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

4

4 に答える 4

7

申し訳ありませんが、私の C# は少し (OK、非常に) 錆びているため、構文エラーがいくつかある可能性がありますが、基本的な考え方は正しいです。

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インターフェイスです。それが、ポリモーフィズムを使い続けることを可能にするものです。

于 2009-05-06T11:32:41.810 に答える
1

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

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

于 2009-05-06T11:21:28.513 に答える
0

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();    
  }
}
于 2009-05-06T11:32:52.900 に答える
0

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

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

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

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

于 2010-02-04T16:26:17.967 に答える