「補(bǔ)課」進(jìn)行時(shí):設(shè)計(jì)模式(12)——適配器模式

1. 前文匯總
「補(bǔ)課」進(jìn)行時(shí):設(shè)計(jì)模式系列
2. 適配器模式
2.1 定義
適配器模式(Adapter Pattern)的定義如下:
Convert the interface of a class into another interface clients expect.Adapterlets classes work together that couldn't otherwise because of incompatibleinterfaces.(將一個(gè)類的接口變換成客戶端所期待的另一種接口,從而使原本因接口不匹配而無法在一起工作的兩個(gè)類能夠在一起工作。)

Target: 目標(biāo)角色,該角色定義把其他類轉(zhuǎn)換為何種接口,也就是我們的期望接口。 Adaptee: 源角色,它是已經(jīng)存在的、運(yùn)行良好的類或?qū)ο螅?jīng)過適配器角色的包裝,它會成為一個(gè)新的角色。 Adapter: 適配器角色,核心角色,其他兩個(gè)角色都是已經(jīng)存在的角色,而適配器角色是需要新建立的,它的職責(zé)非常簡單:通過繼承或是類關(guān)聯(lián)的方式把源角色轉(zhuǎn)換為目標(biāo)角色。
目標(biāo)角色:
public?interface?Target?{
????//?目標(biāo)自己的方法
????void?request();
}
具體目標(biāo)角色實(shí)現(xiàn):
public?class?ConcreteTarget?implements?Target{
????@Override
????public?void?request()?{
????????System.out.println("Target?method?is?run!");
????}
}
源角色:
public?class?Adaptee?{
????public?void?doSomething(){
????????System.out.println("Adaptee?method?doSomething?is?run!");
????}
}
適配器:
public?class?Adapter?extends?Adaptee?implements?Target?{
????@Override
????public?void?request()?{
????????super.doSomething();
????}
}
測試類:
public?class?Test?{
????public?static?void?main(String[]?args)?{
????????//?原有業(yè)務(wù)邏輯
????????Target?target?=?new?ConcreteTarget();
????????target.request();
????????//?經(jīng)過適配器裝飾后的業(yè)務(wù)邏輯
????????Target?target1?=?new?Adapter();
????????target1.request();
????}
}
2.2 優(yōu)點(diǎn)
適配器模式可以讓兩個(gè)沒有任何關(guān)系的類在一起運(yùn)行。 增加了類的透明性:我們訪問的Target目標(biāo)角色,但是具體的實(shí)現(xiàn)都委托給了源角色,而這些對高層次模塊是透明的,也是它不需要關(guān)心的。 提高了類的復(fù)用度:源角色在原有的系統(tǒng)中還是可以正常使用,而在目標(biāo)角色中也可以充當(dāng)新的演員。
3. 案例
適配器模式最好的案例就是我們經(jīng)常使用的電源,我們國家的民用電都是 220V 的交流電,而在日本是使用的 110V 的交流電,而我們的手機(jī)充電,只需要使用 5V 的就可以了,或者還有我們的筆記本電腦,使用的是 19V 或者也有使用 24V 的。
首先,定義一個(gè)輸出交流電的接口,希望是可以輸出 110V 的交流電,因?yàn)閲鴥?nèi)的生產(chǎn)的插頭都是 220V 的,當(dāng)我們購買了直接進(jìn)口到國內(nèi)的電器后,只有 110V 的交流電才能使用:
public?interface?AC?{
????int?convert110v();
}
上面順便帶上了這個(gè)交流電接口的兩個(gè)實(shí)現(xiàn)。
接著,創(chuàng)建一個(gè)源類,因?yàn)槭俏覀儑鴥?nèi)的插頭,目前只能輸出 220V 的交流電
public?class?PowerPlug?{
????public?void?OutPut220V()?{
????????System.out.println("現(xiàn)有插頭只能輸出?220V?電壓");
????}
}
接著,我們裝一個(gè)適配器,將 220V 的電壓轉(zhuǎn)換成 110V 的電壓,可以使我們進(jìn)口回來的電器使用:
public?class?Adapter220?extends?PowerPlug?implements?AC?{
????@Override
????public?void?convert110v()?{
????????this.OutPut220V();
????????System.out.println("通過適配器,將?220V?轉(zhuǎn)換成?110V");
????}
}
這里雖然我們輸出的是 110V 的電壓,但是實(shí)際上還是調(diào)用的之前的 220V 的電壓,我們只是在適配器這一步將電壓轉(zhuǎn)化成了 110V 。
最后是一個(gè)測試類:
public?class?Test?{
????public?static?void?main(String[]?args)?{
????????AC?ac?=?new?Adapter220();
????????ac.convert110v();
????}
}
最后的執(zhí)行結(jié)果:
現(xiàn)有插頭只能輸出?220V?電壓
通過適配器,將?220V?轉(zhuǎn)換成?110V
最后在測試類當(dāng)中,我們雖然是 new 了一個(gè) 220V 的實(shí)例出來,但是在做方法調(diào)用的時(shí)候,直接調(diào)用了適配器的方法,就相當(dāng)于原本的輸出還是 220V ,只是套了一個(gè)將 220V 轉(zhuǎn)成 110V 的外殼。

