趣谈设计模式 | 适配器模式(Adapter):如何让现存对象适用于新的环境?
文章目錄
- 案例:數(shù)據(jù)線(xiàn)轉(zhuǎn)換器
- 適配器模式
- “補(bǔ)償”模式
- 總結(jié)
- 完整代碼與文檔
案例:數(shù)據(jù)線(xiàn)轉(zhuǎn)換器
相信對(duì)于安卓用戶(hù),曾經(jīng)或多或少都有著因?yàn)榻涌诓贿m配而帶來(lái)的苦惱。當(dāng)你在更換手機(jī)時(shí),可能會(huì)因?yàn)樾率謾C(jī)中不配數(shù)據(jù)線(xiàn),而自己的舊手機(jī)的數(shù)據(jù)線(xiàn)接口不同而帶來(lái)煩惱。又或者是當(dāng)我們購(gòu)買(mǎi)耳機(jī)、充電寶、手機(jī)U盤(pán)時(shí)由于接口不同而導(dǎo)致產(chǎn)品無(wú)法使用的情況。
由于當(dāng)年type-c是為了解決快充而實(shí)現(xiàn)的新接口,使用者大部分都是些新生代、追求效率的公司,而市面上大部分公司都仍然使用傳統(tǒng)的Micro USB接口,所以為大家的使用帶來(lái)了困難。
想要解決這個(gè)問(wèn)題的方法有好幾種,第一種就是讓市面統(tǒng)一接口,但是這很明顯不現(xiàn)實(shí),因?yàn)榧夹g(shù)的變革總是會(huì)伴隨著爭(zhēng)議,保守方和革新方的斗爭(zhēng)往往都是長(zhǎng)期的,不可能一下子改變。
而第二種方法則有些特別,既然市面上大多數(shù)都是使用Micro USB,那我們?yōu)楹尾煌瞥鲆环N適配器,讓我們的新接口能夠使用這些傳統(tǒng)的產(chǎn)品呢?
這也就是我們今天所要提到的適配器模式的原理,讓現(xiàn)存的設(shè)備能夠應(yīng)用于新的環(huán)境。
適配器模式
將一個(gè)類(lèi)的接口轉(zhuǎn)換成客戶(hù)希望的另一個(gè)接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類(lèi)可以一起工作。
適配器模式由以下三部分組成
- Target(目標(biāo)):客戶(hù)期望使用的接口
- Adaptee(適配者):我們當(dāng)前具備的,即需要被適配的類(lèi)
- Adapter(適配器):用于適配目標(biāo)和適配者,在內(nèi)部將目標(biāo)接口轉(zhuǎn)換為適配者的接口
適配器模式有兩種實(shí)現(xiàn)方式:類(lèi)適配器和對(duì)象適配器。其中,類(lèi)適配器使用繼承關(guān)系來(lái)實(shí)現(xiàn),對(duì)象適配器使用組合關(guān)系來(lái)實(shí)現(xiàn)。(由于類(lèi)適配器需要用到多繼承,所以在除了C++外的大多數(shù)面向?qū)ο笳Z(yǔ)言中都不適用)
兩種實(shí)現(xiàn)方法的類(lèi)圖如下
下面分別用這兩種方法來(lái)實(shí)現(xiàn)我們的數(shù)據(jù)線(xiàn)適配器
首先為了方便舉例,先給出適配者Type-C和目標(biāo)MicroUSB的代碼
class Type_C { public:virtual ~Type_C() = default;void useTypeC(){std::cout << "使用Type-C數(shù)據(jù)線(xiàn)" << std::endl;} };class MicroUSB { public:virtual ~MicroUSB() = default;virtual void useMicroUSB(){std::cout << "使用Micro USB數(shù)據(jù)線(xiàn)" << std::endl;} };類(lèi)適配器,通過(guò)繼承來(lái)調(diào)用適配者的方法
//類(lèi)適配器,通過(guò)繼承來(lái)實(shí)現(xiàn) class ClassAdapter : public MicroUSB, Type_C { public:void useMicroUSB() override{std::cout << "使用類(lèi)適配器將Type-C轉(zhuǎn)換為Micro USB" << std::endl;useTypeC();} };對(duì)象適配器,通過(guò)組合適配者來(lái)實(shí)現(xiàn)方法的復(fù)用
//對(duì)象適配器 class ObjectAdapter : public MicroUSB { public:ObjectAdapter(Type_C* typeC): _typeC(typeC){}void useMicroUSB() override{std::cout << "使用對(duì)象適配器將Type-C轉(zhuǎn)換為Micro USB" << std::endl;_typeC->useTypeC();} private:Type_C* _typeC; };下面測(cè)試兩種適配器是否成功運(yùn)作
int main() {MicroUSB* micro = new MicroUSB;Type_C* typeC = new Type_C;MicroUSB* objectAdapter = new ObjectAdapter(typeC);MicroUSB* classAdapter = new ClassAdapter;micro->useMicroUSB();cout << endl;objectAdapter->useMicroUSB(); //使用對(duì)象適配器cout << endl; classAdapter->useMicroUSB(); //使用類(lèi)適配器delete micro, typeC, objectAdapter, classAdapter;return 0; }這樣,我們的TYPE-C就可以適配于Micro USB的設(shè)備了
“補(bǔ)償”模式
在上面我們也提到了,適配器模式的主要應(yīng)用場(chǎng)景就是接口不兼容的情況,而在設(shè)計(jì)階段時(shí),我們完全可以通過(guò)統(tǒng)一調(diào)用同一接口來(lái)更加簡(jiǎn)單、直接的解決這個(gè)問(wèn)題。
因此適配器模式并不適合在設(shè)計(jì)的階段實(shí)現(xiàn),因?yàn)槲覀冇懈玫倪x擇,所以我更偏向?qū)⑦m配器模式稱(chēng)為補(bǔ)償模式,當(dāng)系統(tǒng)的開(kāi)發(fā)已經(jīng)完畢,在代碼難以重構(gòu)或者不容易修改的情況下,就可以使用適配器模式來(lái)補(bǔ)救設(shè)計(jì)上的缺陷。最常見(jiàn)的場(chǎng)景就是遺留代碼復(fù)用、類(lèi)庫(kù)遷移等
當(dāng)然上面的說(shuō)法也不是絕對(duì)的,如果我們?cè)谝婚_(kāi)始設(shè)計(jì)的時(shí)候就考慮搭配多種第三方組件,而又不想去迎合它們而改動(dòng)自己的接口,這時(shí)也可以考慮通過(guò)適配器來(lái)解決接口不同的問(wèn)題。
總結(jié)
要點(diǎn)
- 適配器的主要工作就是轉(zhuǎn)換接口以符合客戶(hù)的期望
- 當(dāng)需要使用一個(gè)現(xiàn)有的類(lèi),而接口不符合我們的需求時(shí),就可以通過(guò)適配器來(lái)轉(zhuǎn)換其接口
- 適配器有兩種實(shí)現(xiàn)方法,基于多繼承的類(lèi)適配器和基于組合的對(duì)象適配器
- 通過(guò)適配器可以讓兩個(gè)無(wú)關(guān)聯(lián)的類(lèi)一起允許,提高了類(lèi)的復(fù)用。但是與之相應(yīng)的也會(huì)讓系統(tǒng)更加凌亂,因?yàn)槲覀兠髅餍枰臅r(shí)類(lèi)A,結(jié)果實(shí)際調(diào)用的是適配器中的類(lèi)B,使得代碼不容易理解。
應(yīng)用場(chǎng)景
- 封裝有缺陷的接口設(shè)計(jì)時(shí)
- 需要兼容老版本時(shí)
- 需要統(tǒng)一多個(gè)類(lèi)的接口設(shè)計(jì)時(shí)
- 需要適配多種情況時(shí)
完整代碼與文檔
如果有需要完整代碼或者markdown文檔的同學(xué)可以點(diǎn)擊下面的github鏈接
github
總結(jié)
以上是生活随笔為你收集整理的趣谈设计模式 | 适配器模式(Adapter):如何让现存对象适用于新的环境?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 趣谈设计模式 | 外观模式(Facade
- 下一篇: 趣谈设计模式 | 模板方法模式(Temp