趣谈设计模式 | 适配器模式(Adapter):如何让现存对象适用于新的环境?
文章目錄
- 案例:數據線轉換器
- 適配器模式
- “補償”模式
- 總結
- 完整代碼與文檔
案例:數據線轉換器
相信對于安卓用戶,曾經或多或少都有著因為接口不適配而帶來的苦惱。當你在更換手機時,可能會因為新手機中不配數據線,而自己的舊手機的數據線接口不同而帶來煩惱。又或者是當我們購買耳機、充電寶、手機U盤時由于接口不同而導致產品無法使用的情況。
由于當年type-c是為了解決快充而實現的新接口,使用者大部分都是些新生代、追求效率的公司,而市面上大部分公司都仍然使用傳統的Micro USB接口,所以為大家的使用帶來了困難。
想要解決這個問題的方法有好幾種,第一種就是讓市面統一接口,但是這很明顯不現實,因為技術的變革總是會伴隨著爭議,保守方和革新方的斗爭往往都是長期的,不可能一下子改變。
而第二種方法則有些特別,既然市面上大多數都是使用Micro USB,那我們為何不推出一種適配器,讓我們的新接口能夠使用這些傳統的產品呢?
這也就是我們今天所要提到的適配器模式的原理,讓現存的設備能夠應用于新的環境。
適配器模式
將一個類的接口轉換成客戶希望的另一個接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。
適配器模式由以下三部分組成
- Target(目標):客戶期望使用的接口
- Adaptee(適配者):我們當前具備的,即需要被適配的類
- Adapter(適配器):用于適配目標和適配者,在內部將目標接口轉換為適配者的接口
適配器模式有兩種實現方式:類適配器和對象適配器。其中,類適配器使用繼承關系來實現,對象適配器使用組合關系來實現。(由于類適配器需要用到多繼承,所以在除了C++外的大多數面向對象語言中都不適用)
兩種實現方法的類圖如下
下面分別用這兩種方法來實現我們的數據線適配器
首先為了方便舉例,先給出適配者Type-C和目標MicroUSB的代碼
class Type_C { public:virtual ~Type_C() = default;void useTypeC(){std::cout << "使用Type-C數據線" << std::endl;} };class MicroUSB { public:virtual ~MicroUSB() = default;virtual void useMicroUSB(){std::cout << "使用Micro USB數據線" << std::endl;} };類適配器,通過繼承來調用適配者的方法
//類適配器,通過繼承來實現 class ClassAdapter : public MicroUSB, Type_C { public:void useMicroUSB() override{std::cout << "使用類適配器將Type-C轉換為Micro USB" << std::endl;useTypeC();} };對象適配器,通過組合適配者來實現方法的復用
//對象適配器 class ObjectAdapter : public MicroUSB { public:ObjectAdapter(Type_C* typeC): _typeC(typeC){}void useMicroUSB() override{std::cout << "使用對象適配器將Type-C轉換為Micro USB" << std::endl;_typeC->useTypeC();} private:Type_C* _typeC; };下面測試兩種適配器是否成功運作
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(); //使用對象適配器cout << endl; classAdapter->useMicroUSB(); //使用類適配器delete micro, typeC, objectAdapter, classAdapter;return 0; }這樣,我們的TYPE-C就可以適配于Micro USB的設備了
“補償”模式
在上面我們也提到了,適配器模式的主要應用場景就是接口不兼容的情況,而在設計階段時,我們完全可以通過統一調用同一接口來更加簡單、直接的解決這個問題。
因此適配器模式并不適合在設計的階段實現,因為我們有更好的選擇,所以我更偏向將適配器模式稱為補償模式,當系統的開發已經完畢,在代碼難以重構或者不容易修改的情況下,就可以使用適配器模式來補救設計上的缺陷。最常見的場景就是遺留代碼復用、類庫遷移等
當然上面的說法也不是絕對的,如果我們在一開始設計的時候就考慮搭配多種第三方組件,而又不想去迎合它們而改動自己的接口,這時也可以考慮通過適配器來解決接口不同的問題。
總結
要點
- 適配器的主要工作就是轉換接口以符合客戶的期望
- 當需要使用一個現有的類,而接口不符合我們的需求時,就可以通過適配器來轉換其接口
- 適配器有兩種實現方法,基于多繼承的類適配器和基于組合的對象適配器
- 通過適配器可以讓兩個無關聯的類一起允許,提高了類的復用。但是與之相應的也會讓系統更加凌亂,因為我們明明需要的時類A,結果實際調用的是適配器中的類B,使得代碼不容易理解。
應用場景
- 封裝有缺陷的接口設計時
- 需要兼容老版本時
- 需要統一多個類的接口設計時
- 需要適配多種情況時
完整代碼與文檔
如果有需要完整代碼或者markdown文檔的同學可以點擊下面的github鏈接
github
總結
以上是生活随笔為你收集整理的趣谈设计模式 | 适配器模式(Adapter):如何让现存对象适用于新的环境?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 趣谈设计模式 | 外观模式(Facade
- 下一篇: 趣谈设计模式 | 模板方法模式(Temp