**定義:**適配器模式(Adapter),將一個類的接口轉換成客戶希望的另外一個接口。適配器模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。
**類型:**結構型模式。
**適用性:**
1. 你想使用一個已經存在的類,而它的接口不符合要求。
1. 你想創建一個可以復用的類,該類可以與其他接口不兼容的類協同工作。
1. 你想使用一些已經存在的子類,但是不可能對每一個都進行子類化以匹配它們的接口。可以使用對象適配器來適配它的父類接口。
**類圖:**

**參與角色:**
1. Client,與Target對象類同工作的客戶端.
1. Target,提供滿足Client要求的接口.
1. Adapter,Target的派生類,通過調用Adpatee提供的接口來實現目標接口。
1. Adaptee,已經存在的類,需要適配,也即源接口類。
**概述:**
??????在GoF的《Design Pattern》中提出兩種適配器模式,類適配器和對象適配器。類適配器是通過多重繼承,來實現目標接口的。而對象適配器是通過組合來實現的。應組合/聚合復用原則,所以盡量不使用繼承來實現適配器模式。
??????一說起適配器,大家馬上聯想到的多半會是筆記本電腦的電源適配器了。這個電源適配器也確實和上文提到的適配器模式的思想是一致的。所以這里舉的示例也就使用電源適配器了。
??????這里以ThinkPad的某款筆記本電源適配器為例。輸入電壓是AC100-240V,輸出電壓是DC19V。例如,中國的電網電壓是AC220V,但是如果出差到美國那么當地的電網電壓是AC110V。像很多沒有電源適配器的電器是不能在兩個國家都可以使用的。但是像筆記本電腦卻是可以的。這正是筆記本電腦電源適配器的作用,無論輸入的是AC220V還是AC110V,經過電源適配器之后都可以轉換成筆記本電腦所需要的DC19V。下面便以代碼來簡單描述一下電源適配器所起的作用。(AC,交流電;DC,直流電)
**代碼:**
// 和客戶進行交互的接口,即目標接口,必須提供19V電壓
// 需要注意的是這里的析構函數是虛函數,這是因為保證釋放子類申請的內存
~~~
class CTarget
{
public:
virtual ~CTarget(){}
virtual int SupportComputerVoltage() = 0;
};
~~~
// 電網,提供電壓接口
// 需要注意的是這里的析構函數是虛函數,這是因為保證釋放子類申請的內存
~~~
class CGrid
{
public:
virtual ~CGrid(){}
virtual int SupportVoltage() = 0;
};
~~~
// 美國電網,提供美國電壓110V,也即源接口
~~~
class CUSAGrid : public CGrid
{
public:
virtual int SupportVoltage()
{
return 110;
}
};
~~~
// 中國電網,提供中國電壓220V,也是源接口
~~~
class CPRCGrid : public CGrid
{
public:
virtual int SupportVoltage()
{
return 220;
}
};
~~~
// 適配器,轉換電壓100-240V電壓到19V
~~~
class CAdapater : public CTarget
{
public:
CAdapater(CGrid* _pGrid) : m_pGrid(_pGrid){}
// 實現接口,提供滿足電源所需要的電壓
int SupportComputerVoltage()
{
if (NULL != m_pGrid)
{
cout<<"轉換電壓"<<m_pGrid->SupportVoltage()<<"V至19V"<<endl;
return 19;
}
return 0;
}
private:
CGrid* m_pGrid;
};
~~~
// 客戶端,分別針對中國電網提供的電壓和美國電網提供的電壓進行分析?
~~~
int _tmain(int argc, _TCHAR* argv[])
{
// 中國電網,經過適配器轉換后得到適合筆記本電腦使用的電壓19V
CGrid* pGrid = new CPRCGrid();
CTarget* pTarget = new CAdapater(pGrid);
int nVoltage = pTarget->SupportComputerVoltage();
if (19 != nVoltage)
{
cout<<"提供的電壓有誤,不能正常使用"<<endl;
}
delete pGrid;
delete pTarget;
// 美國電網,經過適配器轉換后得到適合筆記本電腦使用的電壓19V
pGrid = new CUSAGrid();
pTarget = new CAdapater(pGrid);
nVoltage = pTarget->SupportComputerVoltage();
if (19 != nVoltage)
{
cout<<"提供的電壓有誤,不能正常使用"<<endl;
}
delete pGrid;
delete pTarget;
return 0;
}
~~~
**優缺點**:
1. 優點,將已存模塊和客戶端進行了有效的分隔,降低了耦合性,并且最大限度地復用了代碼.
1. 缺點,過多使用適配器模式不利于代碼優化.
參考資料:
1. 《設計模式——可復用面向對象軟件基礎》
1. 《Java與模式》
1. 《大話設計模式》
- 前言
- 設計模式六大原則
- 1——創建型模式之簡單工廠模式
- 2——創建型模式之工廠方法模式
- 3——創建型模式之抽象工廠模式
- 4——創建型模式之單例模式
- 5——創建型模式之建造者模式
- 6——創建型模式之原型模式
- 7——結構型模式之適配器模式
- 8——結構型模式之橋接模式
- 9——結構型模式之組合模式
- 10——結構型模式之裝飾者模式
- 11——結構型模式之外觀模式
- 12——結構型模式之享元模式
- 13——結構型模式之代理模式
- 14——行為型模式之職責鏈模式
- 15——行為型模式之命令模式
- 16——行為型模式之解釋器模式
- 17——行為型模式之迭代器模式
- 18——行為型模式之中介者模式
- 19——行為型模式之備忘錄模式
- 20——行為型模式之觀察者模式
- 21——行為型模式之狀態模式
- 22——行為型模式之策略模式
- 23——行為型模式之模板方法模型
- 24——行為型模式之訪問者模式
- 設計模式總結