1. 程式人生 > >Android開發設計模式之——適配者模式

Android開發設計模式之——適配者模式

適配者模式是也是android中應用很廣泛的設計模式,如我們常見用 BaseAdpter, ArrayAdapter, CursorAdapter,就是用的適配者模式,看到原始碼你是不是對這種設計方式很陌生,沒事,下面我們通過實際的例子來取理解這種設計模式。

一、作用

介面卡模式(Adapter):將一個類的介面轉換成客戶希望的另外一個介面,使得原本由於介面不相容而不能一起工作的那些類可以一起工作。

二、適用場景

1. 業務的介面與工作的類不相容,(比如:類中缺少實現介面的某些方法)但又需要兩者一起工作

2. 在現有介面和類的基礎上為新的業務需求提供介面

三、常見的使用方式

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

(1)類適配模式

大致的意思是新的業務類Xiaomi通過繼承舊業務的類Phone並實現介面Usb來滿足新的業務的一種適配方式,如下圖

Usb介面

public interface Usb {

    void store();

    void takeAlong();
}
Phone類
public class Phone {

    public void call() {
        System.out.println("Phone call");
    }

    public void sms() {
        System.out.println("Phone sms");
    }

    public void takeAlong() {
        System.out.println("Phone takeAlong");
    }
}
適配 Xiaomi 類
/**
 * 類的介面卡模式
 * phone + Usb
 * 將Phone的功能擴充套件到Usb裡
 * @author xuzhaohu
 * 
 */
public class Xiaomi extends Phone implements Usb {

    @Override
    public void store() {
        // TODO Auto-generated method stub
        System.out.println("store implements usb");
    }

}

適配完後使用

        Xiaomi mi1 = new Xiaomi();
        mi1.takeAlong();
        mi1.store();
輸出:

Phone takeAlong
store implements usb

這樣新的業務需求就可以通過適配的 Xiaomi類去滿足了。是不是覺得很簡單呢!!:)  有沒有其他的方式去實現同樣的功能呢?當然有,就是下面要講的物件適配模式。

(2)物件適配模式

實現的方式很簡單,其實就是在適配的時候通過建構函式將舊的業務Phone 當作新的適配類(XiaomiWrapper)一個成員物件去處理,然後適配類只需要實現介面 Usb即可。如下類關係圖

適配類XiaomiWrapper如下,注意takeAlong()方法,是直接呼叫原類物件(Phone)去執行的。

/**
 * 物件的介面卡模式
 * 
 * @author xuzhaohu
 * 
 */
public class XiaomiWrapper implements Usb {

    /**
     * 1.建立一個Wrapper類,持有原類的一個例項,
     * 2.在Wrapper類的方法中,呼叫例項的方法就行
     */
    private Phone phone;

    public XiaomiWrapper(Phone phone) {

        this.phone = phone;
    }

    @Override
    public void store() {
        // TODO Auto-generated method stub
        System.out.println("store implements usb");

    }

    @Override
    public void takeAlong() {
        // TODO Auto-generated method stub
        phone.takeAlong();
    }

}
適配完後通過建構函式將原物件傳入即可。
        XiaomiWrapper mi2 = new XiaomiWrapper(new Phone());
        mi2.takeAlong();
        mi2.store();
輸出:

Phone takeAlong
store implements usb

或許到這裡,你會覺得這種方式很簡單吧。但是如果出現這個Usb介面中有很多方法(大於2個),但是新的業務需求中也只需要其中的一兩個,而且是需要適配很多這樣的業務,這樣的話,用上面的方法每次適配一次就會去實現所有Usb介面中的方法,實際上適配的類中有很多是用不到的,沒有必要把介面中不使用的類也適配進去,這時候,就輪到下面的介面適配模式出場了。

(3)介面適配模式

適配新的業務需求的時候藉助抽象實現類(AbsPhone實現Usb介面),也就說,抽象實現類把Usb介面中的行為都實現了,新的適配是需要跟抽象類對話就行,因為抽象實現類就能滿足了所有適配的需求,並且做到了只適配業務本身的行為,介面中不需要的行為我根本不需要關注。這就是抽象實現類的作用。類圖關係如下:


抽象類AbsPhone實現

/**
 * 介面的介面卡模式
 * 1.藉助於一個抽象類,該抽象類實現了該介面,實現了所有的方法
 * 2.繼承類可以選擇性的實現介面中的方法
 * 
 * @author xuzhaohu
 * 
 */
public abstract class AbsPhone implements Usb {

    public void store() {
        System.out.println("AbsPhone implements usb's store methond");
    }

    public void takeAlong() {
        System.out.println("AbsPhone implements usb's takeAlong methond");
    }
}
適配類只跟AbsPhone打交道,根本不需要關心介面的行為,只顯示自己所要關注的。

如Phone1適配只需要store()行為

public class Phone1 extends AbsPhone {

    public void call() {
        System.out.println("Phone1 call");
    }
    
    public void sms() {
        System.out.println("Phone1 sms");
    }

    public void store() {
        System.out.println("Phone1 need usb's store methond");
    }

}
Phone2適配只需要takeAlong()行為
public class Phone2 extends AbsPhone {

    public void call() {
        System.out.println("Phone2 call");
    }

    public void sms() {
        System.out.println("Phone2 sms");
    }

    public void takeAlong() {
        System.out.println("Phone2 need usb's takeAlong methond");
    }

}
例項化呼叫
        Phone1 p1 = new Phone1();
        Phone2 p2 = new Phone2();
        p1.store();
        p2.takeAlong();
輸出:

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

來一次完整的呼叫

        Phone1 p1 = new Phone1();
        Phone2 p2 = new Phone2();
        p1.store();
        p1.takeAlong();
        p2.takeAlong();
        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

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

總結:適配者模式在android原始碼中有很多這樣的體現,大家看完這個再去看原始碼,是不是會感覺看懂了不少呢?