一、概念
將一個類的接口轉換成客戶希望的另一個接口。Adapter模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。—《設計模式》Gof
二、動機
在軟件系統中,由於應用環境的變化,常常需要將“一些現存的對象”放在新的環境中應用,但是新環境要求的接口是這些現存對象所不滿足的。
如何應對這種“遷移的變化”?如何既能利用現有對象的良好實現,同時又能滿足新的應用環境所要求的接口?
三、適配器模式的實現
// 目標接口(新接口)
class ITarget {
public:
virtual void process() = 0;
};
// 遺留接口(老接口)
class IAdaptee {
public:
virtual void foo(int data) = 0;
virtual int bar() = 0;
};
// 遺留類型,符合老的接口
class OldClass : public IAdaptee {
// ...
};
// 對象適配器
class Adapter: public ITarget { // 繼承
protected:
IAdaptee *pAdaptee; // 組合
public:
Adapter(IAdaptee *pAdaptee) {
this->pAdaptee = pAdaptee;
}
virtual void process() {
int data = pAdaptee->bar();
pAdaptee->foo(data);
}
};
int main() {
IAdaptee *pAdaptee = new OldClass();
ITarget *pTarget = new Adapter(pAdaptee);
pTarget->process();
}
四、類圖結構
五、要點總結
-
Adapter模式主要應用於“希望複用一些現存的類,但是接口又與服用環境要求不一致的情況”,在遺留代碼複用、類庫遷移等方面非常有用。
-
GoF23定義了兩種Adapter模式的結構實現:對象適配器和類適配器。但類適配器採用“多繼承”的實現方式,一般不推薦使用。對象適配器採用“對象組合”的方式,更符合鬆耦合的精神。
-
Adapter模式可以實現的非常靈活,不必拘泥於GoF23中定義的兩種結構。例如,完全可以將Adapter模式中的“現存對象”作爲新的接口方法參數,來達到適配的目的。