Шаблон декоратора с использованием композиции вместо наследования

StackOverflow https://stackoverflow.com/questions/829114

Вопрос

Мое предыдущее понимание шаблона декоратора заключалось в том, что вы наследуете 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();
    }
}

Однако это, по сути, жестко закодировано для декорации, так как бы это было реорганизовано для использования композиции вместо наследования?

Это было полезно?

Решение

Извините, мой 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