【问题标题】:Adapter pattern : Why would we need to subclass the Adaptee?适配器模式:为什么我们需要继承 Adaptee?
【发布时间】:2017-06-14 23:47:15
【问题描述】:

对于对象适配器设计,GoF 指出:

使得覆盖 Adaptee 行为变得更加困难。它需要继承 Adaptee 并使 Adapter 引用子类而不是 Adaptee 本身

我的问题是,当我们创建如下类时为什么需要这个子类化:

class Target {
    public :
    virtual void op() = 0 ;
} ;

class Adaptee {
    public :
    void adapteeOp() {cout<<"adaptee op\n" ;}
} ;

class Adapter : public Target {
    Adaptee *adaptee ;
    public :
    Adapter(Adaptee *a) : adaptee(a) {}
    void op() {
        // added behavior
        cout<<"added behavior\n" ;
        adaptee->adapteeOp() ;
        // more added behavior
        cout<<"more added behavior\n" ;
    }
} ;

main() { //client
    Adapter adapter(new Adaptee) ;
    adapter.op() ;
}

当我也能够覆盖此处的行为时,我无法理解 GoF 提到的子类化要求。

请解释我错过了什么。

【问题讨论】:

    标签: c++ oop inheritance design-patterns polymorphism


    【解决方案1】:

    当我也能够覆盖此处的行为时,我无法理解 GoF 提到的子类化要求。

    我看到了你的困惑。您的示例太简单了,因为它只包含 cout 语句。我没有资格在调用Adaptees 方法之一之前和之后添加cout 语句作为添加任何重要行为。您需要考虑更复杂的场景。

    假设您想将newFunctionality 添加到使用来自Adaptee 的受保护数据的Adaptee。您无法修改 Adaptee,因此您唯一的选择就是对其进行子类化。

    class NewAdaptee : public Adaptee {
        public :
        void adapteeOp() {
            cout<<"adaptee op\n" ; //step 3
        }
    
        void newFunctionality() { //use protected members from Adaptee }
    } ;
    

    上面的代码演示了一个更复杂的用例,即向Adaptee 添加功能,其中子类化是实现此目的的唯一方法。所以你现在想开始在你的Adapter 中使用这个新的Adaptee。如果您使用 object adapter 选项,则需要在 Adaptor 中开始使用 NewAdaptee 引用

    class Adapter : public Target {
        NewAdaptee *adaptee ;
        //more code follows
    }
    

    这有一个直接的问题是您的Adapter 不能再传递Adaptee 的任何直接子类。当他们说这将需要子类化 Adaptee 并使 Adapter 引用子类而不是 Adaptee 本身时,这就是他们的意思。这将带走 对象适配器 方法的优势,该方法允许单个适配器与 Adaptee 的所有子类一起工作。

    注意:类适配器方法中,NewAdaptee 实际上是您的适配器,并且还将继承Target

    【讨论】:

      猜你喜欢
      • 2020-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      • 1970-01-01
      • 2012-05-07
      • 2017-01-01
      相关资源
      最近更新 更多