原文地址:http://www.jellythink.com/archives/108ios
買筆記本電腦,買手機時,都有一個電源適配器,電源適配器又叫外置電源,是小型便攜式電子設備及電子電器的供電電壓變換設備,常見於手機,筆記本電腦上。它的做用是將家裏的220V高電壓轉換成這些電子產品能工做的5V~20V左右穩定的低電壓,使它們能正常工做。就是說,若是沒有這個電源適配器,咱們的手機和電腦就不能進行充電了。設計模式
以前同事去日本出差,因爲工做須要,就將本身的筆記本帶過去了。到了的當晚就悲劇了,筆記本沒法使用。因爲日本的居民用電電壓是110V,而中國是220V,同事的筆記本是220V供電的。次日,同事就去買了一個電壓適配器。若是沒有電壓適配器,估計此次出差都要悲劇了。app
說了這麼多生活中的適配器的例子,那麼在軟件設計、開發過程當中,適配器又是個什麼東西呢?ide
在GOF的《設計模式:可複用面向對象軟件的基礎》中是這樣說的:將一個類的接口轉換成客戶但願的另一個接口。適配器模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。比如日本如今就只提供110V的電壓,而個人電腦就須要220V的電壓,那怎麼辦啦?適配器就是幹這活的,在不兼容的東西之間搭建一座橋樑,讓兩者能很好的兼容在一塊兒工做。函數
在軟件開發中,有的時候系統的數據和行爲都正確,但接口不符合,咱們應該考慮使用適配器模式,目的是使控制範圍以外的一個原有對象與某個接口匹配。舉個例子:在開發一個模塊的時候,有一個功能點實現起來比較費勁,可是,以前有一個項目的模塊實現了同樣的功能點;可是如今這個模塊的接口和以前的那個模塊的接口是不一致的。此時,做爲項目經理的你,該怎麼辦啦?固然是在中間加一層Wrapper了,也就是使用適配器模式,將以前實現的功能點適配進新的項目了。爲何呢?主要是使用適配器模式有如下優勢:測試
每一種設計模式都有它最適用的場合。適配器模式在如下場合下最適用:網站
上圖是適配器模式的第一種實現形式,適配器Adapter繼承自Target和Adaptee類,Adapter類須要重寫Target類的Request函數,在Request中作適當的處理,調用Adaptee類的SepcificRequest。最終,Target實際調用的是Adaptee的SpecificRequest來完成Request的,完成適配;這種叫作類適配器。spa
上圖是適配器的第二種實現形式,適配器Adapter類繼承自Target類,同時,在Adapter類中有一個Adaptee類型的成員變量;Adapter類重寫Request函數時,在Request中,使用Adaptee類型的成員變量調用Adaptee的SpecificRequest函數,最終完成適配;這種叫作對象適配器。設計
既然有了類適配器和對象適配器,那麼在實際中如何在兩者之間作選擇呢?code
類適配器有如下特色:
對象適配器有如下特色:
因爲對象適配器的耦合度比較低,因此在不少的書中都建議使用對象適配器。在咱們實際項目中,也是如此,能使用對象組合的方式,就不使用多繼承的方式。
類適配器的實現代碼
1 /* 2 ** FileName : AdapterPatternDemo 3 ** Author : Jelly Young 4 ** Date : 2013/11/27 5 ** Description : More information, please go to http://www.jellythink.com 6 */ 7 8 #include <iostream> 9 using namespace std; 10 11 // Targets 12 class Target 13 { 14 public: 15 virtual void Request() 16 { 17 cout<<"Target::Request"<<endl; 18 } 19 }; 20 21 // Adaptee 22 class Adaptee 23 { 24 public: 25 void SpecificRequest() 26 { 27 cout<<"Adaptee::SpecificRequest"<<endl; 28 } 29 }; 30 31 // Adapter 32 class Adapter : public Target, Adaptee 33 { 34 public: 35 void Request() 36 { 37 Adaptee::SpecificRequest(); 38 } 39 }; 40 41 // Client 42 int main(int argc, char *argv[]) 43 { 44 Target *targetObj = new Adapter(); 45 targetObj->Request(); 46 47 delete targetObj; 48 targetObj = NULL; 49 50 return 0; 51 }
對象適配器的代碼實現
1 /* 2 ** FileName : AdapterPatternDemo 3 ** Author : Jelly Young 4 ** Date : 2013/11/27 5 ** Description : More information, please go to http://www.jellythink.com 6 */ 7 8 #include <iostream> 9 using namespace std; 10 11 class Target 12 { 13 public: 14 Target(){} 15 virtual ~Target(){} 16 virtual void Request() 17 { 18 cout<<"Target::Request"<<endl; 19 } 20 }; 21 22 class Adaptee 23 { 24 public: 25 void SpecificRequest() 26 { 27 cout<<"Adaptee::SpecificRequest"<<endl; 28 } 29 }; 30 31 class Adapter : public Target 32 { 33 public: 34 Adapter() : m_Adaptee(new Adaptee) {} 35 36 ~Adapter() 37 { 38 if (m_Adaptee != NULL) 39 { 40 delete m_Adaptee; 41 m_Adaptee = NULL; 42 } 43 } 44 45 void Request() 46 { 47 m_Adaptee->SpecificRequest(); 48 } 49 50 private: 51 Adaptee *m_Adaptee; 52 }; 53 54 int main(int argc, char *argv[]) 55 { 56 Target *targetObj = new Adapter(); 57 targetObj->Request(); 58 59 delete targetObj; 60 targetObj = NULL; 61 62 return 0; 63 }
適配器模式很容易理解和實現,在之後的項目中,多多的進行實踐,將學到的理論知識運用到實際的項目中去,寫出漂亮的代碼。