原文地址:LoveDev
適配器模式(Adapter Pattern):將一個(gè)接口轉(zhuǎn)換成調(diào)用者希望的另一個(gè)接口,使接口不兼容的那些類可以一起工作,其別名為包裝類(Wrapper),該模式可以作為類結(jié)構(gòu)型模式,也可以作為對(duì)象結(jié)構(gòu)型模式
適配器模式應(yīng)該是 Android 開(kāi)發(fā)當(dāng)中最常見(jiàn)的幾個(gè)設(shè)計(jì)模式之一了,各種各樣的列表(ListView,GridView,RecyclerView)都要使用一個(gè) Adapter 的類
使用場(chǎng)景:
- 系統(tǒng)需要使用現(xiàn)有的類,而這些類的接口不符合系統(tǒng)的需要
- 想要建立一個(gè)可以重復(fù)使用的類,用于與一些彼此之間沒(méi)有太大關(guān)聯(lián)的一些類,包括一些可能在將來(lái)引進(jìn)的類一起工作
適配器模式一個(gè)可以分為三個(gè)適配器:
<h1 id="CLASS"> 類適配器 </h1>

- Target:目標(biāo)角色,可以是一個(gè)抽象類或接口,由于是類適配器,不能為具體類
- Adaptee:適配者類,一般是一個(gè)具體類,包含期望的業(yè)務(wù)方法,某些情況下可能沒(méi)有適配者的源代碼
- Adapter:適配器類,可以把源接口轉(zhuǎn)換成目標(biāo)接口

使用 Mac 的同學(xué)應(yīng)該很熟悉上面的兩個(gè)東西,Apple 的充電器可以把兩腳的充電頭拔掉換成一個(gè)更長(zhǎng)且是三腳的充電頭,下面就以這兩個(gè)東西為示例,完成一個(gè)適配器模式,示例代碼:
Target 類:
public interface Power {
/**
* 充電
*/
void charge();
}
在正常情況下用兩腳的插頭已經(jīng)足夠滿足需求了,但是現(xiàn)在所處的環(huán)境只有三腳的插板,現(xiàn)在就可以把只支持三腳的插板看做是現(xiàn)有的接口,而默認(rèn)的充電是不支持此接口的,這時(shí)候就需要用到三腳的適配器,示例代碼:
Adaptee 類,期望實(shí)現(xiàn)的功能:
public class ExtensionPower {
public void specificPower() {
LogUtils.i("用三腳,1.8米延長(zhǎng)線充電");
}
}
Adapter 類,三腳延長(zhǎng)線:
public class PowerAdapter extends ExtensionPower implements Power{
@Override
public void charge() {
super.specificPower();
}
}
Client 類:
public class Client {
PowerAdapter powerAdapter = new PowerAdapter();
powerAdapter.charge();
}
利用適配器模式就可以解決上述的問(wèn)題,并且非常符合開(kāi)閉原則
<h1 id="OBJECT"> 對(duì)象適配器 </h1>

對(duì)象適配器不在使用類適配器繼承再實(shí)現(xiàn)的方式,而是采用直接關(guān)聯(lián)的方式,區(qū)別就在于 adapter 類:
public class PowerAdapter implements Power {
private ExtensionPower extensionPower;
// 此處改為直接關(guān)聯(lián)的方式
public PowerAdapter(ExtensionPower extensionPower) {
this.extensionPower = extensionPower;
}
@Override
public void charge() {
this.extensionPower.specificPower();
}
}
<h1 id="DEFAULT"> 缺省適配器 </h1>

當(dāng)我們只想實(shí)現(xiàn)一個(gè)接口 N 多個(gè)方法中的一個(gè)時(shí),就要用到該模式了,在具體實(shí)現(xiàn)類和接口中間設(shè)計(jì)一個(gè)抽象類實(shí)現(xiàn)該接口,并提供所有方法的空實(shí)現(xiàn),具體實(shí)現(xiàn)類就可以繼承抽象類,這樣就可以選擇自己想要實(shí)現(xiàn)的某一接口
舉個(gè)栗子:一個(gè)已婚人士的生活是吃飯,睡覺(jué)以及啪啪啪,但是現(xiàn)在需要需要添加一個(gè)新的物種叫做單身狗,單身狗當(dāng)然是沒(méi)有啪啪啪功能的,這個(gè)時(shí)候就需要?jiǎng)?chuàng)建一個(gè)抽象類實(shí)現(xiàn)已婚人士這個(gè)接口,并讓單身狗繼承實(shí)現(xiàn)吃飯和睡覺(jué)的功能
示例代碼:
已婚人士接口:
public interface MarriedPeople {
/**
* 吃飯
*/
void eat();
/**
* 睡覺(jué)
*/
void sleep();
/**
* 啪啪啪
*/
void papapa();
}
抽象類:
public abstract class Adults implements MarriedPeople {
@Override
public void eat() {
}
@Override
public void sleep() {
}
@Override
public void papapa() {
}
}
單身狗:
public class SingleDog extends Adults {
public void eat() {
LogUtils.i("吃飯");
}
public void sleep() {
LogUtils.i("睡覺(jué)");
}
}
說(shuō)了這么多,該到總結(jié)的時(shí)候了,適配器模式優(yōu)點(diǎn):
- 使用適配器類達(dá)到重用先用適配者類,無(wú)須修改原有結(jié)構(gòu)
- 增加類的透明性和復(fù)用性,具體業(yè)務(wù)邏輯都封裝在適配者類中,提高適配者的復(fù)用性