適配器模式是將一個(gè)舊類的接口窖认,通過抽象而后組合的方式畦贸,獲得一個(gè)新的接口以拓展新的功能。
動(dòng)機(jī)
在一切應(yīng)用中樟凄,因?yàn)樵瓉淼慕涌谝呀?jīng)不能滿足當(dāng)前新的需求聘芜。新功能和原有類相差較大,無法統(tǒng)一抽象缝龄,所以需要用新的方式將新功能擴(kuò)展出來汰现。
方法
和電源轉(zhuǎn)接插座一樣,在原有接口和新功能接口之間再分裝一個(gè)接口叔壤。實(shí)現(xiàn)來接口和新接口之家的適配瞎饲。
具體來說,新建一個(gè)包含原有類的抽象類炼绘,在該抽象類的內(nèi)部多定義一個(gè)新的適配接口用來實(shí)現(xiàn)新的功能嗅战。
這里使用中式插頭(CCnOutlet),為原有接口俺亮,現(xiàn)要拓展英式插頭(CEnOutlet)驮捍,所以這里就多定義了一個(gè)新適配器(Adapter), 一面繼承了原有中式插頭脚曾,又添加了擴(kuò)展槽(IAdaptee)支持了英式插頭东且。
例子代碼如下:
#include <iostream>
using namespace std;
class CCnOutlet //原有功能實(shí)現(xiàn)
{
public:
virtual void useCnplug()
{
cout<<"use Cn plug."<<endl;
}
};
class IAdaptee
{
public:
void virtual useplug() = 0;
};
class CEnOutlet : public IAdaptee //新添加的功能實(shí)現(xiàn)
{
public:
void useplug()
{
cout<<"use En plug."<<endl;
}
};
class Adapter : public CCnOutlet//公有繼承目標(biāo), 適配原有接口
{
private:
IAdaptee *pA;//適配對(duì)象本讥, 新添加插槽珊泳,支持新功能實(shí)現(xiàn)
public:
Adapter(IAdaptee *p)
{
pA = p;
}
void useCnplug()
{
pA->useplug();
}
};
int main()
{
CEnOutlet *pEn = new CEnOutlet;//英式插座
CCnOutlet *pCn = new Adapter(pEn); //接口對(duì)接
pCn->useCnplug();
delete pEn;
delete pCn;
return 0;
}
一般的鲁冯, 適配器模式是將一個(gè)類的接口,通過抽象后組合的方式色查,獲得一個(gè)新的晓褪。它的類圖顯示如下:
應(yīng)用場(chǎng)景
- 使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。
- 已有代碼需要再次擴(kuò)展的情況下综慎,如:遺留代碼復(fù)用、類庫遷移的情形
代碼示例
#include <iostream>
using namespace std;
class Target { // Target勤庐,客戶期望的接口示惊,可以使具體或抽象的類,也可以是接口
public:
virtual void Request() = 0;
virtual ~Target(){};
};
class Adaptee { // 需適配的類
public:
void SpecificRequest() { cout << "Adaptee" << endl; }
};
class Adapter : public Target { // 通過內(nèi)部包裝一個(gè)Adaptee對(duì)象愉镰,把源接口轉(zhuǎn)換為目標(biāo)接口:
private:
Adaptee* adaptee;
public:
Adapter() { adaptee = new Adaptee(); }
void Request() { adaptee->SpecificRequest(); } // 調(diào)用Request()方法會(huì)轉(zhuǎn)換成調(diào)用adaptee.SpecificRequest()
~Adapter() { delete adaptee; }
};
int main() {
Target* target = new Adapter();
target->Request();
delete target;
return 0;
}