适配器模式:为什么我们需要继承Adaptee?

时间:2017-01-29 20:08:41

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

对于对象适配器设计,GoF声明:

  

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

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

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所提到的子类化要求。

请解释我错过了什么。

1 个答案:

答案 0 :(得分:2)

  

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

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

想象一下,您想要使用Adaptee中受保护数据的Adaptee添加新功能。您无法修改Adaptee,因此您唯一的选择是将其子类化。

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

    void newFunctionality() { //use protected members from Adaptee }
} ;

上面的代码演示了向Adaptee添加功能的更复杂的用例,其中子类化是实现此目的的唯一方法。因此,您现在想要在Adaptee中开始使用这个新的Adapter。如果您使用对象适配器选项,则需要开始使用NewAdaptee

中的Adaptor引用
class Adapter : public Target {
    NewAdaptee *adaptee ;
    //more code follows
}

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

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