Decorator Pattern Usando Composição Em vez de herança
-
06-07-2019 - |
Pergunta
O meu entendimento anterior do padrão decorador era que você Window
herdar com WindowDecorator
, em seguida, nos métodos substituídos, fazer algum trabalho adicional antes de chamar a implementação do Window
de métodos referidos. Semelhante ao seguinte:
public class Window
{
public virtual void Open()
{
// Open the window
}
}
public class LockableWindow : Window // Decorator
{
public virtual void Open()
{
// Unlock the window
base.Open();
}
}
No entanto, esta essencialmente hardcodes a decoração, então como é que este ser reformulado para composição uso em vez de herança?
Solução
Desculpe, o meu C # é um um pouco (OK, muito) enferrujado, portanto, pode haver alguns erros de sintaxe, mas a idéia básica é certo.
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();
}
}
A principal coisa a notar é a nova interface IWindow
; Isso é o que permite que você continue usando polimorfismo.
Outras dicas
O ponto do padrão decorador é melhorar um objecto com alguma funcionalidade (por exemplo a adição de armazenamento, a um fluxo) de uma maneira que é transparente para o chamador. A fim de usá-lo de forma mais eficaz, você quer ser capaz de trocar na implementação decorada, sem refatoração de código, o que implica, basicamente, que você precisa para manter a hierarquia de herança.
Qual é a sua preocupação real, ou seja, o que significa "Este disco-códigos de decoração" realmente significa? Que tipo de problemas você imagina querer resolver? Pode ser que a decoração não é a abordagem correta ...
Você simplesmente tem seu LockableWindow definir um construtor que recebe uma instância do tipo, Janela, que vai decorar. Você também pode fazê-lo através de propriedades.
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();
}
}
O meu entendimento do padrão decorador é que ele se destina a permitir uma melhoria de tempo de execução das capacidades de um objeto. Na explicação wikipedia, eles se concentram em uma pilha de componentes para este fim.
eu não falo C # em tudo, então este é (obviamente) php-ish. Parece que a idéia correta seria:
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 mais experientes, por favor, explicar a desconexão.