Java結(jié)構(gòu)型設(shè)計(jì)模式之適配器模式詳解
適配器模式
適配器模式(Adapter Pattern)又叫做變壓器模式,屬于結(jié)構(gòu)型設(shè)計(jì)模式。
它的功能是將一個(gè)類(lèi)的接口變成客戶(hù)端所期望的另一種接口,從而使原本因接口不匹配而導(dǎo)致無(wú)法在一起工作的兩個(gè)類(lèi)能夠一起工作。
適配器就像一個(gè)中間層,起著轉(zhuǎn)化委托的作用,將一種接口轉(zhuǎn)化為另一種符合需求的接口。
分類(lèi)
適配器模式有3種形式:類(lèi)適配器、對(duì)象適配器、接口適配器
類(lèi)適配器:
類(lèi)適配器的原理就是通過(guò)繼承來(lái)實(shí)現(xiàn)適配器功能。
對(duì)象適配器:
對(duì)象適配器的原理就是通過(guò)組合來(lái)實(shí)現(xiàn)適配器功能。
接口適配器:
接口適配器的主要原理就是原理利用抽象類(lèi)實(shí)現(xiàn)接口,并且空實(shí)現(xiàn)接口眾多方法。
應(yīng)用場(chǎng)景
1.已經(jīng)存在的類(lèi),它的方法和需求不匹配(方法結(jié)果相同或相以)的情況。
2.適配器模式不是軟件設(shè)計(jì)階段考慮的設(shè)計(jì)模式,是隨著軟件維護(hù),由于不同產(chǎn)品、不同廠家造成功能類(lèi)似以而接口不相同情況下的解決方案。
說(shuō)明:
當(dāng)系統(tǒng)存在兩種接口A和B,客戶(hù)端只支持訪問(wèn)A接口,但是當(dāng)前系統(tǒng)沒(méi)有A接口對(duì)象,但是有B接口對(duì)象,但客戶(hù)無(wú)法識(shí)別B接口,因此需要通過(guò)一個(gè)適配器C,將B接口內(nèi)容轉(zhuǎn)換成A接口,從而使得客戶(hù)能夠從A接口獲取得到B接口內(nèi)容。
舉例:在不同的國(guó)家電源電壓不一致,但是筆記本充電器通常有一個(gè)電壓范圍,其相當(dāng)于使用了適配器,讓其適應(yīng)了不通過(guò)國(guó)家的電壓。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
1.能提高類(lèi)的透明性和復(fù)用,現(xiàn)有的類(lèi)復(fù)用但不需要改變。
2.目標(biāo)類(lèi)和適配器類(lèi)解耦,提高程序的擴(kuò)展性。
3.在很多業(yè)務(wù)場(chǎng)景中符合開(kāi)閉原則。
缺點(diǎn):
1.適配器編寫(xiě)過(guò)程需要全面考慮,可能會(huì)增加系統(tǒng)的復(fù)雜性。
2.增加代碼閱讀難度,降低代碼可讀性,過(guò)多使用適配器會(huì)使系統(tǒng)代碼變得凌亂。
主要角色
1.目標(biāo)角色(Target)
目標(biāo)角色也就是期望的接口
2.源角色(Adaptee)
存在于系統(tǒng)中,內(nèi)容滿(mǎn)足客戶(hù)需求(需轉(zhuǎn)換),但接口不匹配的接口實(shí)例
3.適配器(Adapter)
將源角色(Adaptee)轉(zhuǎn)化為目標(biāo)角色(Target)的類(lèi)實(shí)例
適配器模式各角色之間的關(guān)系
需要的是Target接口,但Target接口設(shè)有一個(gè)實(shí)例符合需求,而Adaptee實(shí)例符合需求;但是無(wú)法直接使用Adaptee(接口不兼容);因此需要一個(gè)適配器(Adapter)來(lái)進(jìn)行中轉(zhuǎn),讓Adaptee能轉(zhuǎn)化為T(mén)arget接口形式;
類(lèi)適配器
類(lèi)適配器的原理就是通過(guò)繼承來(lái)實(shí)現(xiàn)適配器功能。
讓Adapter實(shí)現(xiàn)Target接口,并且繼承Adaptee,這樣Adapter就具備Target和Adaptee的特性,就可以將兩者進(jìn)行轉(zhuǎn)化。
舉例:以不同設(shè)備使用不同交流電為例,通過(guò)電源適配器進(jìn)行轉(zhuǎn)換說(shuō)明。
創(chuàng)建目標(biāo)角色(Target)
public interface Target { int out(); }
創(chuàng)建源角色(Adaptee)
public class Adaptee{ public int input() { System.out.println("輸入交流電: 220V"); return 220; } }
創(chuàng)建適配器(Adapter)
public class Adapter extends Adaptee implements Target { @Override public int out() { int input220V = super.input(); int output = input220V / 2; System.out.println("輸出交流電: " + output + "V"); return output; } }
客戶(hù)端調(diào)用
public static void main(String[] args) { Target adapter = new Adapter(); int result = adapter.out(); System.out.println(result); }
輸入交流電: 220V
輸出交流電: 110V
110
對(duì)象適配器
對(duì)象適配器的原理就是通過(guò)組合來(lái)實(shí)現(xiàn)適配器功能。
讓Adapter實(shí)現(xiàn)Target接口,然后內(nèi)部持有Adaptee實(shí)例,然后再Target接口規(guī)定的方法內(nèi)轉(zhuǎn)換Adaptee。
創(chuàng)建目標(biāo)角色(Target)
public interface Target { int out(); }
創(chuàng)建源角色(Adaptee)
public class Adaptee{ public int input() { System.out.println("輸入交流電: 220V"); return 220; } }
創(chuàng)建適配器(Adapter)
public class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } @Override public int out() { int output = adaptee.input() / 2; System.out.println("輸出交流電: " + output + "V"); return output; } }
客戶(hù)端調(diào)用
public static void main(String[] args) { Target adapter = new Adapter(new Adaptee()); int result = adapter.out(); System.out.println(result); }
輸入交流電: 220V
輸出交流電: 110V
110
接口適配器
接口適配器的關(guān)注點(diǎn)與類(lèi)適配器和對(duì)象適配器的關(guān)注點(diǎn)不太一樣,類(lèi)適配器和對(duì)象適配器著重于將系統(tǒng)存在的一個(gè)角色(Adaptee)轉(zhuǎn)化成目標(biāo)接口(Target)所需內(nèi)容,而接口適配器的使用場(chǎng)景是解決接口方法過(guò)多,如果直接實(shí)現(xiàn)接口,那么類(lèi)會(huì)多出許多空實(shí)現(xiàn)的方法,類(lèi)顯得很臃腫。此時(shí),使用接口適配器就能讓我們只實(shí)現(xiàn)我們需要的接口方法,目標(biāo)更清晰。
接口適配器的主要原理就是原理利用抽象類(lèi)實(shí)現(xiàn)接口,并且空實(shí)現(xiàn)接口眾多方法。
創(chuàng)建目標(biāo)角色(Target)
public interface Target { int out1(); int out2(); int out3(); int out4(); }
創(chuàng)建源角色(Adaptee)
public class Adaptee{ public int input() { System.out.println("輸入交流電: 220V"); return 220; } }
創(chuàng)建適配器(Adapter)
public class Adapter implements Target { protected Adaptee adaptee; public Adapter(Adaptee adaptee){ this.adaptee = adaptee; } @Override public int out1() { int input220V = adaptee.input(); int output = input220V / 1; System.out.println("輸出交流電: " + output + "V"); return output; } @Override public int out2() { int input220V = adaptee.input(); int output = input220V / 2; System.out.println("輸出交流電: " + output + "V"); return output; } @Override public int out3() { return 0; } @Override public int out4() { return 0; } }
客戶(hù)端調(diào)用
public static void main(String[] args) { Target adapter = new Adapter(new Adaptee()); adapter.out1(); System.out.println("---------------------"); adapter.out2(); System.out.println("---------------------"); Target adapter2 = new Adapter(new Adaptee()) { @Override public int out3() { int input220V = adaptee.input(); int output = input220V / 3; System.out.println("輸出交流電: " + output + "V"); return output; } }; adapter2.out3(); System.out.println("---------------------"); Target adapter3 = new Adapter(new Adaptee()) { @Override public int out4() { int input220V = adaptee.input(); int output = input220V / 4; System.out.println("輸出交流電: " + output + "V"); return output; } }; adapter3.out4(); }
輸入交流電: 220V
輸出交流電: 220V
---------------------
輸入交流電: 220V
輸出交流電: 110V
---------------------
輸入交流電: 220V
輸出交流電: 73V
---------------------
輸入交流電: 220V
輸出交流電: 55V
到此這篇關(guān)于Java結(jié)構(gòu)型設(shè)計(jì)模式之適配器模式詳解的文章就介紹到這了,更多相關(guān)Java適配器模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
三分鐘教你如何在IDEA中快速創(chuàng)建工程的方法
這篇文章主要介紹了三分鐘教你如何在IDEA中快速創(chuàng)建工程的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04springboot如何實(shí)現(xiàn)前后端分離跨域訪問(wèn)
這篇文章主要介紹了springboot如何實(shí)現(xiàn)前后端分離跨域訪問(wèn)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12java圖論普利姆及克魯斯卡算法解決最小生成樹(shù)問(wèn)題詳解
這篇文章主要為大家介紹了java圖論普利姆算法及克魯斯卡算法解決最小生成樹(shù)問(wèn)題的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11Java多線(xiàn)程之鎖學(xué)習(xí)(增強(qiáng)版)
這篇文章主要為大家詳細(xì)介紹了Java多線(xiàn)程中鎖的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),對(duì)我們了解線(xiàn)程有一定幫助,需要的可以參考一下2023-02-02Java中動(dòng)態(tài)地改變數(shù)組長(zhǎng)度及數(shù)組轉(zhuǎn)Map的代碼實(shí)例分享
這篇文章主要介紹了Java中動(dòng)態(tài)地改變數(shù)組長(zhǎng)度及數(shù)組轉(zhuǎn)map的代碼分享,其中轉(zhuǎn)Map利用到了java.util.Map接口,需要的朋友可以參考下2016-03-03Spring?Boot?3.1中整合Spring?Security和Keycloak的方法
本文介紹在最新的SpringBoot3.1版本之下,如何將Keycloak和Spring?Security一起跑起來(lái),文中結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2023-06-06