Java中的適配器模式詳解
1、適配器模式概述
在軟件設(shè)計(jì)中可能出現(xiàn):需要開發(fā)的具有某種業(yè)務(wù)功能的組件在現(xiàn)有的組件庫中已經(jīng)存在,但它們與當(dāng)前系統(tǒng)的接口規(guī)范不兼容,如果重新開發(fā)這些組件成本又很高,這時(shí)用適配器模式能很好地解決這些問題。
適配器模式介紹
適配器模式(Adapter Pattern)將某個(gè)類的接口轉(zhuǎn)換成客戶端期望的另一個(gè)接口表示,主的目的是兼容性,讓原本因接口不匹配不能一起工作的兩個(gè)類可以協(xié)同工作。其別名為包裝器(Wrapper)。
適配器模式屬于結(jié)構(gòu)型模式。
主要分為三類:類適配器模式、對(duì)象適配器模式、接口適配器模式。
適配器工作原理
1、適配器模式:將一個(gè)類的接口轉(zhuǎn)換成另一種接口.讓原本接口不兼容的類可以兼容
2、從用戶的角度看不到被適配者,是解耦的
3、用戶調(diào)用適配器轉(zhuǎn)化出來的目標(biāo)接口方法,適配器再調(diào)用被適配者的相關(guān)接口方法
4、用戶收到反饋結(jié)果,感覺只是和目標(biāo)接口交互,如圖
適配器模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 客戶端通過適配器可以透明地調(diào)用目標(biāo)接口。
- 復(fù)用了現(xiàn)存的類,程序員不需要修改原有代碼而重用現(xiàn)有的適配者類。
- 將目標(biāo)類和適配者類解耦,解決了目標(biāo)類和適配者類接口不一致的問題。
- 在很多業(yè)務(wù)場(chǎng)景中符合開閉原則。
缺點(diǎn):
- 適配器編寫過程需要結(jié)合業(yè)務(wù)場(chǎng)景全面考慮,可能會(huì)增加系統(tǒng)的復(fù)雜性。
- 增加代碼閱讀難度,降低代碼可讀性,過多使用適配器會(huì)使系統(tǒng)代碼變得凌亂。
2、適配器模式的結(jié)構(gòu)圖
適配器模式的結(jié)構(gòu)
適配器模式(Adapter)包含以下主要角色。
- 目標(biāo)(Target)接口:當(dāng)前系統(tǒng)業(yè)務(wù)所期待的接口,它可以是抽象類或接口。
- 適配者(Adaptee)類:它是被訪問和適配的現(xiàn)存組件庫中的組件接口。
- 適配器(Adapter)類:它是一個(gè)轉(zhuǎn)換器,通過繼承或引用適配者的對(duì)象,把適配者接口轉(zhuǎn)換成目標(biāo)接口,讓客戶按目標(biāo)接口的格式訪問適配者。
適配器模式的結(jié)構(gòu)圖
類適配器模式:
對(duì)象適配器模式:
3、類適配器模式的實(shí)現(xiàn)
類適配器模式介紹
適配器通過繼承適配者類,實(shí)現(xiàn)目標(biāo)接口,完成適配者 ----》目標(biāo)接口的轉(zhuǎn)換。
類適配器模式的實(shí)現(xiàn)
編寫適配者類:
public class Voltage220V { //輸出220V的電壓 public int output220V(){ int src = 220; System.out.println("電壓為"+src+"伏"); return src; } }
編寫目標(biāo)接口:當(dāng)前系統(tǒng)業(yè)務(wù)所期待的接口
public interface IVoltage5V { public int output5V(); }
編寫適配器:繼承適配者類,實(shí)現(xiàn)目標(biāo)接口
public class VoltageAdapter extends Voltage220V implements IVoltage5V{ @Override public int output5V() { //調(diào)用Voltage220V里的方法得到220V int srcV = output220V(); //把220V轉(zhuǎn)換成5V并輸出 int dstV =srcV / 44 ; return dstV; } }
編寫業(yè)務(wù):
public class Phone { public void charging(IVoltage5V iVoltage5V){ if (iVoltage5V.output5V() == 5){ System.out.println("適配后的電壓5V,可以充電"); }else { System.out.println("適配后的電壓異常,不能充電"); } } }
編寫測(cè)試類:
public class client { public static void main(String[] args) { System.out.println("測(cè)試類適配器模式:"); Phone phone = new Phone(); phone.charging(new VoltageAdapter()); } }
類適配器模式注意事項(xiàng)
1、Java是單繼承機(jī)制,所以類適配器需要繼承適配者類這一點(diǎn)算是一個(gè)缺點(diǎn),因?yàn)檫@要求目標(biāo)必須是接口,有一定局限性;
2、適配者類的方法在Adapter(適配器)中都會(huì)暴露出來,也增加了使用的成本。
3、由于其繼承了適配者類,所以它可以根據(jù)需求重寫適配者類的方法,使得Adapter(適配器)的靈活性增強(qiáng)了。
4、對(duì)象適配器模式的實(shí)現(xiàn)
對(duì)象適配器模式的介紹
1、基本思路和類的適配器模式相同,只是將Adapter類作修改,不是繼承適配者類,而是持有適配者類的實(shí)例,以解決兼容性的問題。即:持有適配者類,實(shí)現(xiàn)目標(biāo)接口,完成適配者->目標(biāo)接口的適配
2、根據(jù)“合成復(fù)用原則”,在系統(tǒng)中盡量使用關(guān)聯(lián)關(guān)系來替代繼承關(guān)系。
3、對(duì)象適配器模式是適配器模式常用的一種
對(duì)象適配器模式的實(shí)現(xiàn)
編寫適配者類:
public class Voltage220V { //輸出220V的電壓 public int output220V(){ int src = 220; System.out.println("電壓為"+src+"伏"); return src; } }
編寫目標(biāo)接口:當(dāng)前系統(tǒng)業(yè)務(wù)所期待的接口
public interface IVoltage5V { public int output5V(); }
編寫適配器:持有適配者類,實(shí)現(xiàn)目標(biāo)接口
public class VoltageAdapter implements IVoltage5V { private Voltage220V voltage220V; //傳入適配者類實(shí)例 public VoltageAdapter(Voltage220V voltage220V){ this.voltage220V = voltage220V; } @Override public int output5V() { int dst = 0; //調(diào)用Voltage220V里的方法得到220V if (null != voltage220V){ int srcV = voltage220V.output220V(); dst = srcV / 44; } return dst; } }
編寫業(yè)務(wù):
public class Phone { public void charging(IVoltage5V iVoltage5V){ if (iVoltage5V.output5V() == 5){ System.out.println("適配后的電壓5V,可以充電"); }else { System.out.println("適配后的電壓異常,不能充電"); } } }
編寫測(cè)試類:
public class client { public static void main(String[] args) { System.out.println("對(duì)象適配器模式:"); Phone phone = new Phone(); phone.charging(new VoltageAdapter(new Voltage220V())); } }
對(duì)象適配器模式注意事項(xiàng)
1、對(duì)象適配器和類適配器其實(shí)算是同一種思想,只不過實(shí)現(xiàn)方式不同。
根據(jù)合成復(fù)用原則,使用組合替代繼承,所以它解決了類適配器必須繼承適配者的局限性問題,也不再要求目標(biāo)必須是接口。
2、使用成本更低,更靈活。
5、接口適配器的實(shí)現(xiàn)
接口適配器的介紹
1、一些書籍稱為:適配器模式(Default Adapter Pattern)或缺省適配器模式。
2、當(dāng)不需要全部實(shí)現(xiàn)接口提供的方法時(shí),這時(shí)我們可以使用一個(gè)抽象類作為中間件,即適配器,用這個(gè)抽象類實(shí)現(xiàn)接口,而在抽象類中所有的方法都進(jìn)行置空,那么我們?cè)賱?chuàng)建抽象類的繼承類,而且重寫我們需要使用的那幾個(gè)方法即可。
3、接口適配器適用于一個(gè)接口不想使用其所有的方法的情況。
接口適配器模式的實(shí)現(xiàn)
適配者作為接口:
public interface Interface4 { void m1(); void m2(); void m3(); void m4(); }
接口適配器:
public abstract class AbsAdapter implements Interface4{ @Override public void m1() { } @Override public void m2() { } @Override public void m3() { } @Override public void m4() { } }
測(cè)試類:
public class Client extends AbsAdapter{ public static void main(String[] args) { Client client = new Client(); client.m2(); } @Override public void m2() { System.out.println("使用了m2方法"); } }
到此這篇關(guān)于Java中的適配器模式詳解的文章就介紹到這了,更多相關(guān)Java適配器模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java運(yùn)行時(shí)數(shù)據(jù)區(qū)劃分原理解析
這篇文章主要介紹了Java運(yùn)行時(shí)數(shù)據(jù)區(qū)劃分原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Java刷題之最小k個(gè)數(shù)的思路及具體實(shí)現(xiàn)
這篇文章主要介紹了Java刷題之最小k個(gè)數(shù)的思路及具體實(shí)現(xiàn),最小K個(gè)數(shù)是一個(gè)經(jīng)典的top-K問題,可以通過整體排序、建立小根堆或大根堆的方式解決,排序方式時(shí)間復(fù)雜度較高,適合數(shù)據(jù)量小的場(chǎng)景,小根堆適合k較小的情況,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-10-10ssm框架controller層返回json格式數(shù)據(jù)到頁面的實(shí)現(xiàn)
這篇文章主要介紹了ssm框架controller層返回json格式數(shù)據(jù)到頁面的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09如何使用@AllArgsConstructor和final 代替 @Autowired
這篇文章主要介紹了使用@AllArgsConstructor和final 代替 @Autowired方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09spring boot下mybatis配置雙數(shù)據(jù)源的實(shí)例
這篇文章主要介紹了spring boot下mybatis配置雙數(shù)據(jù)源的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09Java統(tǒng)計(jì)一個(gè)字符串在另外一個(gè)字符串出現(xiàn)次數(shù)的方法
這篇文章主要介紹了Java統(tǒng)計(jì)一個(gè)字符串在另外一個(gè)字符串出現(xiàn)次數(shù)的方法,涉及java字符串遍歷、正則匹配等相關(guān)操作技巧,需要的朋友可以參考下2018-03-03Java 基礎(chǔ)之內(nèi)部類詳解及實(shí)例
這篇文章主要介紹了 Java 基礎(chǔ)之內(nèi)部類詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03