装饰器模式的继承
Posted
技术标签:
【中文标题】装饰器模式的继承【英文标题】:Inheritance of decorator pattern 【发布时间】:2021-07-18 01:28:41 【问题描述】:在装饰器模式中,一个抽象类实现一个接口,一个具体类(装饰器)扩展抽象类。如果具体类直接实现接口而不是通过抽象类继承,模式的功能会怎样?
【问题讨论】:
【参考方案1】:抽象类不是必需的。从 GoF 书的第 179 页开始,
当您只需要添加一个职责时,无需定义抽象的装饰器类。当您处理现有的类层次结构而不是设计新的类层次结构时,通常会出现这种情况。在这种情况下,您可以合并装饰者的职责 用于将组件的请求转发到 ConcreteDecorator。
Head First Design 的一个类似问题是,What is the reason for moving the instance variable into an abstract class in the decorator pattern?
【讨论】:
【参考方案2】:最初的设计模式一书 (GoF) 于 1994 年出版,使用 C++ 和 SmallTalk 作为示例。 IIRC,C++ 没有语言级接口(至少在 1994 年没有)。当书告诫时
编程到接口,而不是实现
您应该将interface这个词解释为一个概念,而不是一种语言结构。
例如,在 C++ 中,使用专门定义纯虚函数的抽象类来模拟接口是很常见的。 GoF 书中的许多 C++ 示例都是这样做的。
有一个strong relationship between abstract classes and interfaces,实际上它们可以互换。
至于装饰器模式,我猜想总是可以装饰一个界面。例如,考虑这样的界面:
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;
因此,无论您使用抽象类还是接口,装饰器模式都没有区别。
【讨论】:
以上是关于装饰器模式的继承的主要内容,如果未能解决你的问题,请参考以下文章