【问题标题】:Inheritance of decorator pattern装饰器模式的继承
【发布时间】:2021-07-18 01:28:41
【问题描述】:

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

【问题讨论】:

    标签: inheritance design-patterns decorator-pattern


    【解决方案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;
          }
      }
      

      因此,无论您使用抽象类还是接口,装饰器模式都没有区别。

      【讨论】:

        猜你喜欢
        • 2012-09-04
        • 2012-07-24
        • 2015-05-27
        • 1970-01-01
        • 2014-03-07
        • 2018-04-17
        • 2011-09-18
        • 2020-11-06
        • 2011-03-01
        相关资源
        最近更新 更多