对于对象适配器设计,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所提到的子类化要求。
请解释我错过了什么。
答案 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
。