設計模式-適配器模式

適配者模式是也是android中應用很普遍的設計模式,如咱們常見用 BaseAdpter, ArrayAdapter, CursorAdapter,就是用的適配者模式,看到源碼你是否是對這種設計方式很陌生,沒事,下面咱們經過實際的例子來取理解這種設計模式。java

1、做用android

適配器模式(Adapter):將一個類的接口轉換成客戶但願的另一個接口,使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。設計模式

2、適用場景app

1. 業務的接口與工做的類不兼容,(好比:類中缺乏實現接口的某些方法)但又須要二者一塊兒工做ide

2. 在現有接口和類的基礎上爲新的業務需求提供接口函數

3、常見的使用方式oop

仍是以Usb接口和Phone手機類的產品舉例子,假設設計的Phone類中有 call(), sms(), takeAlong()屬性方法,而在設計Usb接口時定義了 store(), takeAlong()的行爲。若是如今有新的業務需求,須要生成 Xiaomi手機類具備 Phone類和Usb接口二者功能,假設Phone類和Usb接口已經在業務上投入使用,很顯然,去修改原類中的方法和接口的行爲去知足如今的新業務需求是不可取的,那麼如今適配者模式就派上用場了。this

(1)類適配模式spa

大體的意思是新的業務類Xiaomi經過繼承舊業務的類Phone並實現接口Usb來知足新的業務的一種適配方式,以下圖.net

Usb接口

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. public interface Usb {  
  2.   
  3.     void store();  
  4.   
  5.     void takeAlong();  
  6. }  

Phone類

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. public class Phone {  
  2.   
  3.     public void call() {  
  4.         System.out.println("Phone call");  
  5.     }  
  6.   
  7.     public void sms() {  
  8.         System.out.println("Phone sms");  
  9.     }  
  10.   
  11.     public void takeAlong() {  
  12.         System.out.println("Phone takeAlong");  
  13.     }  
  14. }  

適配 Xiaomi 類

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. /** 
  2.  * 類的適配器模式 
  3.  * phone + Usb 
  4.  * 將Phone的功能擴展到Usb裏 
  5.  * @author xuzhaohu 
  6.  *  
  7.  */  
  8. public class Xiaomi extends Phone implements Usb {  
  9.   
  10.     @Override  
  11.     public void store() {  
  12.         // TODO Auto-generated method stub  
  13.         System.out.println("store implements usb");  
  14.     }  
  15.   
  16. }  

 

適配完後使用

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. Xiaomi mi1 = new Xiaomi();  
  2. mi1.takeAlong();  
  3. mi1.store();  

輸出:

 

Phone takeAlong
store implements usb

這樣新的業務需求就能夠經過適配的 Xiaomi類去知足了。是否是以爲很簡單呢!!:)  有沒有其餘的方式去實現一樣的功能呢?固然有,就是下面要講的對象適配模式。

(2)對象適配模式

實現的方式很簡單,其實就是在適配的時候經過構造函數將舊的業務Phone 看成新的適配類(XiaomiWrapper)一個成員對象去處理,而後適配類只須要實現接口 Usb便可。以下類關係圖

適配類XiaomiWrapper以下,注意takeAlong()方法,是直接調用原類對象(Phone)去執行的。

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. /** 
  2.  * 對象的適配器模式 
  3.  *  
  4.  * @author xuzhaohu 
  5.  *  
  6.  */  
  7. public class XiaomiWrapper implements Usb {  
  8.   
  9.     /** 
  10.      * 1.建立一個Wrapper類,持有原類的一個實例, 
  11.      * 2.在Wrapper類的方法中,調用實例的方法就行 
  12.      */  
  13.     private Phone phone;  
  14.   
  15.     public XiaomiWrapper(Phone phone) {  
  16.   
  17.         this.phone = phone;  
  18.     }  
  19.   
  20.     @Override  
  21.     public void store() {  
  22.         // TODO Auto-generated method stub  
  23.         System.out.println("store implements usb");  
  24.   
  25.     }  
  26.   
  27.     @Override  
  28.     public void takeAlong() {  
  29.         // TODO Auto-generated method stub  
  30.         phone.takeAlong();  
  31.     }  
  32.   
  33. }  

適配完後經過構造函數將原對象傳入便可。

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. XiaomiWrapper mi2 = new XiaomiWrapper(new Phone());  
  2. mi2.takeAlong();  
  3. mi2.store();  

輸出:

 

Phone takeAlong
store implements usb

或許到這裏,你會以爲這種方式很簡單吧。可是若是出現這個Usb接口中有不少方法(大於2個),可是新的業務需求中也只須要其中的一兩個,並且是須要適配不少這樣的業務,這樣的話,用上面的方法每次適配一次就會去實現全部Usb接口中的方法,實際上適配的類中有不少是用不到的,沒有必要把接口中不使用的類也適配進去,這時候,就輪到下面的接口適配模式出場了。

(3)接口適配模式

適配新的業務需求的時候藉助抽象實現類(AbsPhone實現Usb接口),也就說,抽象實現類把Usb接口中的行爲都實現了,新的適配是須要跟抽象類對話就行,由於抽象實現類就能知足了全部適配的需求,而且作到了只適配業務自己的行爲,接口中不須要的行爲我根本不須要關注。這就是抽象實現類的做用。類圖關係以下:

抽象類AbsPhone實現

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. /** 
  2.  * 接口的適配器模式 
  3.  * 1.藉助於一個抽象類,該抽象類實現了該接口,實現了全部的方法 
  4.  * 2.繼承類能夠選擇性的實現接口中的方法 
  5.  *  
  6.  * @author xuzhaohu 
  7.  *  
  8.  */  
  9. public abstract class AbsPhone implements Usb {  
  10.   
  11.     public void store() {  
  12.         System.out.println("AbsPhone implements usb's store methond");  
  13.     }  
  14.   
  15.     public void takeAlong() {  
  16.         System.out.println("AbsPhone implements usb's takeAlong methond");  
  17.     }  
  18. }  

適配類只跟AbsPhone打交道,根本不須要關心接口的行爲,只顯示本身所要關注的。

 

如Phone1適配只須要store()行爲

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. public class Phone1 extends AbsPhone {  
  2.   
  3.     public void call() {  
  4.         System.out.println("Phone1 call");  
  5.     }  
  6.       
  7.     public void sms() {  
  8.         System.out.println("Phone1 sms");  
  9.     }  
  10.   
  11.     public void store() {  
  12.         System.out.println("Phone1 need usb's store methond");  
  13.     }  
  14.   
  15. }  

Phone2適配只須要takeAlong()行爲

 

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. public class Phone2 extends AbsPhone {  
  2.   
  3.     public void call() {  
  4.         System.out.println("Phone2 call");  
  5.     }  
  6.   
  7.     public void sms() {  
  8.         System.out.println("Phone2 sms");  
  9.     }  
  10.   
  11.     public void takeAlong() {  
  12.         System.out.println("Phone2 need usb's takeAlong methond");  
  13.     }  
  14.   
  15. }  

實例化調用

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. Phone1 p1 = new Phone1();  
  2. Phone2 p2 = new Phone2();  
  3. p1.store();  
  4. p2.takeAlong();  

輸出:

 

Phone1 need usb's store methond
Phone2 need usb's takeAlong methond

來一次完整的調用

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
  1. Phone1 p1 = new Phone1();  
  2. Phone2 p2 = new Phone2();  
  3. p1.store();  
  4. p1.takeAlong();  
  5. p2.takeAlong();  
  6. p2.store();  

輸出:

 

Phone1 need usb's store methond
AbsPhone implements usb's takeAlong methond
Phone2 need usb's takeAlong methond
AbsPhone implements usb's store methond

這樣很清晰的知道適配的什麼方法了。

相關文章
相關標籤/搜索