对于对象适配器设计,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
。