在装饰器模式中,一个抽象类实现一个接口,一个具体类(装饰器)扩展抽象类。如果具体类直接实现接口而不是通过抽象类继承接口,模式的功能会发生什么?
问问题
45 次
2 回答
2
抽象类不是必需的。从 GoF 书的第 179 页开始,
当您只需要添加一个职责时,无需定义抽象的装饰器类。当您处理现有的类层次结构而不是设计新的层次结构时,通常会出现这种情况。在这种情况下,您可以将 Decorator 将请求转发到组件的职责合并到 ConcreteDecorator 中。
Head First Design 的一个类似问题是,在装饰器模式中将实例变量移动到抽象类的原因是什么?
于 2021-04-24T03:11:28.420 回答
1
最初的设计模式书 (GoF) 于 1994 年出版,使用 C++ 和 SmallTalk 作为示例。IIRC,C++ 没有语言级接口(至少在 1994 年没有)。当书告诫
编程到接口,而不是实现
您应该将接口一词解释为一个概念,而不是一种语言结构。
例如,在 C++ 中,使用专门定义纯虚函数的抽象类来模拟接口是很常见的。GoF 书中的许多 C++ 示例都是这样做的。
抽象类和接口之间有很强的关系,以至于它们实际上可以互换。
至于装饰器模式,我猜想总是可以装饰一个界面。例如,考虑这样的接口:
public interface IFace
{
void Command(Arg1 arg1, Arg2 arg2);
Ret1 Query(Arg3);
}
AFAICT,你总是可以写一个装饰器IFace
——至少是一个退化的装饰器:
public class MyFace : IFace
{
private readonly IFace inner;
public MyFace(IFace inner)
{
this.inner = inner;
}
public void Command(Arg1 arg1, Arg2 arg2)
{
// Consider doing something interesting here...
inner.Command(arg1, arg2);
// ... or here
}
public Ret1 Query(Arg3)
{
// Consider doing something interesting here...
Ret1 ret = inner.Query(arg3);
// ... or here
return ret;
}
}
因此,无论您使用抽象类还是接口,对装饰器模式都没有影响。
于 2021-04-24T06:41:09.237 回答