1

在装饰器模式中,一个抽象类实现一个接口,一个具体类(装饰器)扩展抽象类。如果具体类直接实现接口而不是通过抽象类继承接口,模式的功能会发生什么?

4

2 回答 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 回答