Java | 设计模式-适配器模式
繼代理模式后又來到適配器模式啦,想看之前的也有哦。持續(xù)更新中哦。讓我們一起加油吧兄弟們,干他。
很喜歡一句話:”八小時內(nèi)謀生活,八小時外謀發(fā)展".
你好,如果喜歡,請一起堅持!!
共勉
一張舊照,恍惚間想起舊人
Java設(shè)計模式-適配器模式 理論代碼相結(jié)合
- 一、前言
- 1)概述
- 2)介紹
- 3)角色結(jié)構(gòu)
- 4)使用場景
- 二、類適配器
- 2.1、代碼
- 三、對象適配器
- 代碼
- 擴(kuò)展
- 四、總結(jié)
- 五、自言自語
一、前言
1)概述
? 在現(xiàn)實生活中,經(jīng)常出現(xiàn)兩個對象因接口不兼容而不能在一起工作的實例,這時需要第三者進(jìn)行適配。例如,講中文的人同講英文的人對話時需要一個翻譯,用直流電的筆記本電腦接交流電源時需要一個電源適配器,用計算機訪問照相機的 SD 內(nèi)存卡時需要一個讀卡器等。還有像下面這張圖一樣:
? 在軟件設(shè)計中也可能出現(xiàn):需要開發(fā)的具有某種業(yè)務(wù)功能的組件在現(xiàn)有的組件庫中已經(jīng)存在,但它們與當(dāng)前系統(tǒng)的接口規(guī)范不兼容,如果重新開發(fā)這些組件成本又很高,這時用適配器模式能很好地解決這些問題。
2)介紹
適配器模式(Adapter)的定義如下:將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口,使得原本由于接口不兼容而不能一起工作的那些類能一起工作。適配器模式分為類結(jié)構(gòu)型模式和對象結(jié)構(gòu)型模式兩種,前者類之間的耦合度比后者高,且要求程序員了解現(xiàn)有組件庫中的相關(guān)組件的內(nèi)部結(jié)構(gòu),所以應(yīng)用相對較少些。
Adapter模式的宗旨:保留現(xiàn)有類所提供的服務(wù),向客戶提供接口,以滿足客戶的期望。
3)角色結(jié)構(gòu)
適配器模式(Adapter)包含以下主要角色:
- 目標(biāo)(Target)接口:當(dāng)前系統(tǒng)業(yè)務(wù)所期待的接口,它可以是抽象類或接口。
- 適配者(Adaptee)類:它是被訪問和適配的現(xiàn)存組件庫中的組件接口。
- 適配器(Adapter)類:它是一個轉(zhuǎn)換器,通過繼承或引用適配者的對象,把適配者接口轉(zhuǎn)換成目標(biāo)接口,讓客戶按目標(biāo)接口的格式訪問適配者。
4)使用場景
適配器模式(Adapter)通常適用于以下場景。
- 以前開發(fā)的系統(tǒng)存在滿足新系統(tǒng)功能需求的類,但其接口同新系統(tǒng)的接口不一致。(就是所謂的加一層,一層不行就加兩層)😁
- 使用第三方提供的組件,但組件接口定義和自己要求的接口定義不同。
二、類適配器
當(dāng)客戶在接口中定義了他期望的行為時,我們就可以應(yīng)用適配器模式,提供一個實現(xiàn)該接口的類,并且擴(kuò)展已有的類,通過創(chuàng)建子類來實現(xiàn)適配。
實現(xiàn)方式:定義一個適配器類來實現(xiàn)當(dāng)前系統(tǒng)的業(yè)務(wù)接口,同時又繼承現(xiàn)有組件庫中已經(jīng)存在的組件。
我們直接用之前的那個圖來做個例子:中國人到了歐洲,的給自己電腦充電,但因為自己電腦是雙叉,歐式是三叉,這中間就得需要一個轉(zhuǎn)換器。
2.1、代碼
目標(biāo)(Target)接口:即圖中的歐式三叉
public interface EuropeSocket {/** 歐式三叉 通電 接通電 插座*/String useEuropesocket(); }// 歐式三叉實現(xiàn)類 public class EuropeSocketImpl implements EuropeSocket {@Overridepublic String useEuropesocket() {String msg ="使用歐式三叉充電";return msg;} }適配者(Adaptee):即中國雙叉
public interface ChineseSocket {/*** 使用中國雙叉充電* @return*/String useChineseSocket(); }// 中國插頭的實現(xiàn)類 public class ChineseSocketImpl implements ChineseSocket {@Overridepublic String useChineseSocket() {String msg="使用中國雙叉充電";return msg;} }適配器(Adapter)類:
/*** 定義適配器類 中國雙叉轉(zhuǎn)為歐洲三叉**/ public class ChineseAdapterEurope extends EuropeSocketImpl implements ChineseSocket {@Overridepublic String useChineseSocket() {System.out.println("使用轉(zhuǎn)換器轉(zhuǎn)換完成");return useEuropesocket();} }電腦類
public class Computer {public String useChineseSocket(ChineseSocket chineseSocket) {if(chineseSocket == null) {throw new NullPointerException("sd card null");}return chineseSocket.useChineseSocket();} }測試:
public class Client {public static void main(String[] args) {Computer computer = new Computer();ChineseSocket chineseSocket = new ChineseSocketImpl();System.out.println(computer.useChineseSocket(chineseSocket));System.out.println("------------");ChineseAdapterEurope adapter = new ChineseAdapterEurope();System.out.println(computer.useChineseSocket(adapter));/*** 輸出:* 使用中國雙叉充電* ------------* 使用轉(zhuǎn)換器轉(zhuǎn)換完成* 使用歐式三叉充電*/} }上述代碼就是簡單的演示了適配器的使用。
注:類適配器模式違背了合成復(fù)用原則。類適配器是客戶類有一個接口規(guī)范的情況下可用,反之不可用。
三、對象適配器
對象適配器”通過組合除了滿足“用戶期待接口”還降低了代碼間的不良耦合。在工作中推薦使用“對象適配”。
實現(xiàn)方式:對象適配器模式可釆用將現(xiàn)有組件庫中已經(jīng)實現(xiàn)的組件引入適配器類中,該類同時實現(xiàn)當(dāng)前系統(tǒng)的業(yè)務(wù)接口。
題目還是和上面一樣的哈。代碼其實差異很小
代碼
目標(biāo)(Target)接口:即圖中的歐式三叉
public interface EuropeSocket {/** 歐式三叉 通電 接通電 插座*/String useEuropesocket(); }// 歐式三叉實現(xiàn)類 public class EuropeSocketImpl implements EuropeSocket {@Overridepublic String useEuropesocket() {String msg ="使用歐式三叉充電";return msg;} }適配者(Adaptee):即中國雙叉
public interface ChineseSocket {/*** 使用中國雙叉充電* @return*/String useChineseSocket(); }// 中國插頭的實現(xiàn)類 public class ChineseSocketImpl implements ChineseSocket {@Overridepublic String useChineseSocket() {String msg="使用中國雙叉充電";return msg;} }適配器(Adapter)類: 就是這個適配器內(nèi)做了一些更改 從繼承改為了成員變量的方式
public class ChineseAdapterEurope implements ChineseSocket {private EuropeSocket europeSocket;public ChineseAdapterEurope(EuropeSocket europeSocket) {this.europeSocket = europeSocket;}@Overridepublic String useChineseSocket() {System.out.println("使用轉(zhuǎn)換器轉(zhuǎn)換完成");return europeSocket.useEuropesocket();} }電腦類
public class Computer {public String useChineseSocket(ChineseSocket chineseSocket) {if(chineseSocket == null) {throw new NullPointerException("sd card null");}return chineseSocket.useChineseSocket();} }測試:
public class Client {public static void main(String[] args) {Computer computer = new Computer();ChineseSocket chineseSocket = new ChineseSocketImpl();System.out.println(computer.useChineseSocket(chineseSocket));System.out.println("------------");//這里做了更改EuropeSocket europeSocket=new EuropeSocketImpl();ChineseAdapterEurope adapter = new ChineseAdapterEurope(europeSocket);System.out.println(computer.useChineseSocket(adapter));/*** 輸出:* 使用中國雙叉充電* ------------* 使用轉(zhuǎn)換器轉(zhuǎn)換完成* 使用歐式三叉充電*/} }這就是對象適配器啦,
適合于解決問題常見:
- 需要的東西有,但不能用,且短時間無法改造。即,使得一個功能適合不同的環(huán)境。
- 在開發(fā)中,系統(tǒng)的數(shù)據(jù)、行為都匹配,但接口不符時,可以考慮適配器。
- 希望復(fù)用一些現(xiàn)存的類,但是接口又與復(fù)用環(huán)境的要求不一致,應(yīng)該考慮用適配器模式。(使用一個已經(jīng)存在的類,但它的接口(即,方法),與需要的不相同時)
擴(kuò)展
適配器模式(Adapter)可擴(kuò)展為雙向適配器模式,雙向適配器類既可以把適配者接口轉(zhuǎn)換成目標(biāo)接口,也可以把目標(biāo)接口轉(zhuǎn)換成適配者接口。
四、總結(jié)
優(yōu)點:
- 客戶端通過適配器可以透明地調(diào)用目標(biāo)接口。
- 復(fù)用了現(xiàn)存的類,程序員不需要修改原有代碼而重用現(xiàn)有的適配者類。提高了類的復(fù)用
- 將目標(biāo)類和適配者類解耦,解決了目標(biāo)類和適配者類接口不一致的問題。靈活性好
- 可以讓任何兩個沒有關(guān)聯(lián)的類一起運行
- 在很多業(yè)務(wù)場景中符合開閉原則
其缺點是:
- 適配器編寫過程需要結(jié)合業(yè)務(wù)場景全面考慮,可能會增加系統(tǒng)的復(fù)雜性。
- 增加代碼閱讀難度,降低代碼可讀性,過多使用適配器會使系統(tǒng)代碼變得凌亂。(如:明明看到調(diào)用的是 A 接口,其實內(nèi)部被適配成了 B 接口的實現(xiàn),一個系統(tǒng)如果太多出現(xiàn)這種情況,無異于一場災(zāi)難)
五、自言自語
你卷我卷,大家卷,什么時候這條路才是個頭啊。😇(還是直接上天吧)
有時候也想停下來歇一歇,一直做一個事情,感覺挺難堅持的。😁
你好,如果你正巧看到這篇文章,并且覺得對你有益的話,就給個贊吧,讓我感受一下分享的喜悅吧,蟹蟹。🤗
如若有寫的有誤的地方,也請大家不嗇賜教!!
同樣如若有存在疑惑的地方,請留言或私信,定會在第一時間回復(fù)你。
持續(xù)更新中
總結(jié)
以上是生活随笔為你收集整理的Java | 设计模式-适配器模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java设计模式-建造者模式 理论代码相
- 下一篇: JUC系列(九)| ThreadPool