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



我的问题是,为什么我们在创建clase时需要以下子类:

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

请解释我错过的重点是什么。

最佳答案



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

假设您想将newFunctionality添加到使用Adaptee中 protected 数据的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

08-26 10:16