C# 使用组合而不是继承的装饰器模式
我以前对decorator模式的理解是,您使用C# 使用组合而不是继承的装饰器模式,c#,design-patterns,decorator,composition,C#,Design Patterns,Decorator,Composition,我以前对decorator模式的理解是,您使用WindowDecorator继承Window,然后在重写的方法中,在调用Window对所述方法的实现之前做一些额外的工作。与以下内容类似: public class Window { public virtual void Open() { // Open the window } } public class LockableWindow : Window // Decorator { publi
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
界面;这就是允许您继续使用多态性的原因。您只需让您的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();
}
}
我对decorator模式的理解是,它旨在允许在运行时增强对象的功能。在维基百科的解释中,他们将重点放在用于此目的的组件堆栈上 我根本不会说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
哦,有经验的人,请解释一下断开连接的原因。没有那么生疏,尽管实现接口方法不需要虚拟的,谢谢。事实上,从.NET1.0开始我就没有写过任何东西。只是这个问题不需要任何新的语言特性。这里的一个问题是LockableWindow对Window不是多态的。编辑:刚刚注意到这在OP中是真实的。