Decorator Pattern Using Composition Instead of Inheritance

两盒软妹~` 提交于 2019-12-25 01:43:46

问题


My previous understanding of the decorator pattern was that you inherit Window with WindowDecorator, then in the overridden methods, do some additional work before calling the Window's implementation of said methods. Similar to the following:

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

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

However this essentially hardcodes the decoration, so how would this be refactored to use composition instead of inheritance?


回答1:


Sorry, my C# is a a bit (OK, very) rusty, so there may be a few syntax errors, but the basic idea is right.

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();
    }
}

The key thing to notice is the new IWindow interface; that's what allows you to keep using polymorphism.




回答2:


The point of the Decorator pattern is to enhance an object with some functionality (e.g. adding buffering to a stream) in a way that's transparent to the caller. In order to use it most effectively, you want to be able to swap in the decorated implementation without refactoring code, which basically implies that you need to maintain the inheritance hierarchy.

What's your actual concern, i.e. what does "this hard-codes the decoration" really mean? What kind of problems do you envision wanting to solve? It may be that decoration is not quite the right approach...




回答3:


You simply have your LockableWindow define a constructor that takes an instance of the type, Window, that it will decorate. You could also do it via properties.

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();    
  }
}



回答4:


My understanding of the decorator pattern is that it is intended to allow a run-time enhancement of an object's capabilities. In the wikipedia explanation, they focus on a component stack for this purpose.

I don't speak C# at all, so this is (obviously) php-ish. It seems that the correct idea would be:

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

Oh Experienced Ones, please explain the disconnect.



来源:https://stackoverflow.com/questions/829114/decorator-pattern-using-composition-instead-of-inheritance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!