DesignPattern - 适配器模式【结构型】
歡迎關(guān)注微信公眾號(hào):FSA全棧行動(dòng) 👋
一、適配器模式介紹
適配器模式(Adapter Pattern)屬于結(jié)構(gòu)型模式,作為兩個(gè)不兼容的接口之間的橋梁。
- 常見(jiàn)的幾類適配器
- 接口的適配器模式【空實(shí)現(xiàn)】:不想實(shí)現(xiàn)一個(gè)接口中所有的方法時(shí),可以創(chuàng)建一個(gè) Adapter,實(shí)現(xiàn)所有方法,在寫(xiě)別的類的時(shí)候,繼承這個(gè) Adapter 類即可。
- 類的適配器模式【繼承(舊) + 實(shí)現(xiàn)(新)】:想將一個(gè)類轉(zhuǎn)換成滿足另一個(gè)新接口的類時(shí),可以使用類的適配器模式,創(chuàng)建一個(gè)新類,繼承原有的類,實(shí)現(xiàn)新的接口即可。
- 對(duì)象的適配器模式【組合】:想將一個(gè)對(duì)象轉(zhuǎn)換成滿足另一個(gè)新接口的對(duì)象時(shí),可以創(chuàng)建一個(gè)適配器類,持有原類的一個(gè)實(shí)例,在適配器類的方法中,調(diào)用實(shí)例的方法就行。
- 應(yīng)用場(chǎng)景
- 電腦需要讀取內(nèi)存卡的數(shù)據(jù),讀卡器就是適配器
- 日常使用的轉(zhuǎn)換頭,如電源轉(zhuǎn)換頭,電壓轉(zhuǎn)換頭
- 系統(tǒng)需要使用現(xiàn)在的類,而這些類的接口不符合系統(tǒng)的需要(如:JDK 中 InputStreamReader 就是適配器)
- JDBC 使用的就是適配器模式,jDBC 給出一個(gè)客戶端通用的抽象接口,每一個(gè)具體數(shù)據(jù)庫(kù)廠商,如 SQL Server、Oracle、MySQL 等,會(huì)開(kāi)發(fā)對(duì)應(yīng)的 JDBC 驅(qū)動(dòng),這個(gè) JDBC 驅(qū)動(dòng)就是一個(gè)介于 JDBC 接口和數(shù)據(jù)庫(kù)引擎接口之間的適配器軟件。
- 優(yōu)點(diǎn)
- 可以讓任何兩個(gè)沒(méi)有關(guān)聯(lián)的類一起運(yùn)行,使得原本由于接口不兼容而不能一起工作的那些類可以一起工作
- 增加靈活度,提高復(fù)用性,適配器類可以在多個(gè)系統(tǒng)使用,符合開(kāi)閉原則
- 缺點(diǎn)
- 整體類的調(diào)用鏈路增加,本來(lái) A 可以直接調(diào)用 C,使用適配器后,是 A 調(diào)用 B,B 再調(diào)用 C
補(bǔ)充:適配器模式用于設(shè)計(jì)完成之后,發(fā)現(xiàn)類、接口之間無(wú)法一起工作,需要進(jìn)行填坑。
二、適配器模式代碼實(shí)現(xiàn)
1、接口適配器模式
有些接口中有多個(gè)抽象方法,當(dāng)我們寫(xiě)該接口的實(shí)現(xiàn)類時(shí),必須實(shí)現(xiàn)該接口的所有方法,有時(shí)會(huì)覺(jué)得比較冗余,因?yàn)椴⒉皇撬械姆椒ǘ际俏覀冃枰?#xff0c;只需要實(shí)現(xiàn)部分接口就可以了。
創(chuàng)建支付網(wǎng)關(guān)接口:
/*** 支付網(wǎng)關(guān)接口** @author GitLqr*/ public interface IPayGateway {/*** 下單*/void order();/*** 退款*/void refund();/*** 查詢*/void query();/*** 發(fā)紅包*/void sendRedPack();... }創(chuàng)建接口適配器類:
/*** 接口適配器:提供所有接口的默認(rèn)實(shí)現(xiàn)** @author GitLqr*/ public class PayGatewayAdapter implements IPayGateway {@Overridepublic void order() {}@Overridepublic void refund() {}@Overridepublic void query() {}@Overridepublic void sendRedPack() {}}創(chuàng)建具體業(yè)務(wù)類:
/*** 視頻VIP訂購(gòu):只有訂購(gòu)和退款功能** @author GitLqr*/ public class VideoVipOrder extends PayGatewayAdapter {@Overridepublic void order() {System.out.println("視頻VIP 訂購(gòu)成功");}@Overridepublic void refund() {System.out.println("視頻VIP 退款成功");} }說(shuō)明:相比于實(shí)現(xiàn) IPayGateway 接口,繼承 PayGatewayAdapter 適配器類,可以讓 VideoVipOrder 中代碼簡(jiǎn)潔不少。
2、類的適配器模式
想將一個(gè)類轉(zhuǎn)換成滿足另一個(gè)新接口的類時(shí),可以使用類的適配器模式,創(chuàng)建一個(gè)新類,繼承原有的類,實(shí)現(xiàn)新的接口即可。
創(chuàng)建 舊類:
說(shuō)明:【舊類】對(duì)應(yīng)的是工程中原本就存在的類,能夠穩(wěn)定運(yùn)行,但是不支持一些新功能。實(shí)際開(kāi)發(fā)中,這些舊類實(shí)現(xiàn)可能相當(dāng)復(fù)雜(可能是屎山),不能輕易改動(dòng)!!
/*** 舊類:端口,只能支持usb** @author GitLqr*/ public class Port {public void usb(Object usbDevice) {System.out.println("插入 usb 設(shè)備");} }創(chuàng)建 新功能接口:
說(shuō)明:該【新功能接口】一般擁有 舊類 中的方法,方便后續(xù)面向接口編程。
/*** 新接口:需要支持舊端口類型(usb)的同時(shí),支持更多的新端口類型(如 typec、usb4)** @author GitLqr*/ public interface INewPort {void usb(Object usbDevice);void typec(Object typecDevice);void usb4(Object usb4Device); }創(chuàng)建 新類:
說(shuō)明:【新類】需要繼承【舊類】,同時(shí)實(shí)現(xiàn)【新功能接口】
/*** 新類:端口適配器【擴(kuò)展塢】** @author GitLqr*/ public class PortAdapter extends Port implements INewPort {@Overridepublic void typec(Object typecDevice) {System.out.println("插入 type-c 設(shè)備");}@Overridepublic void usb4(Object usb4Device) {System.out.println("插入 雷電4 設(shè)備");}}使用:
public static void main(String[] args) {...INewPort newPort = new PortAdapter();newPort.usb(usbDevice); // 老功能 也能正常使用newPort.typec(typecDevice);newPort.usb4(usb4Device); }3、對(duì)象的適配器模式
想將一個(gè)對(duì)象轉(zhuǎn)換成滿足另一個(gè)新接口的對(duì)象時(shí),可以創(chuàng)建一個(gè)適配器類,持有原類的一個(gè)實(shí)例,在適配器類的方法中,調(diào)用實(shí)例的方法就行。
對(duì)象的適配器更像是一種包裝(或增強(qiáng)),實(shí)際功能還需要借助原對(duì)象來(lái)執(zhí)行處理,就比如充電器插頭問(wèn)題,插頭轉(zhuǎn)換器只是改變了充電器插頭的類型,實(shí)際上給手機(jī)充電的,還是充電器本身。
創(chuàng)建 充電器類:
/*** 充電器** @author GitLqr*/ public class Charger {void charge() {System.out.println("充電中...");} }創(chuàng)建 新接口(支持多種插頭轉(zhuǎn)換):
/*** 接口:各式插頭** @author GitLqr*/ public interface IPlugConverter {/*** 雙腳插頭充電*/void chargeOnTwoPin();/*** 三腳插頭充電*/void chargeOnThreePin();/*** 三腳插頭充電(港版插座)*/void chargeOnThreePinHK();}創(chuàng)建 滿足 新接口 的 適配器類:
/*** 充電器插頭適配器** @author GitLqr*/ public class ChargerPlugAdapter implements IPlugConverter {private Charger charger;public ChargerPlugAdapter(Charger charger) {super();this.charger = charger;}@Overridepublic void chargeOnTwoPin() {charger.charge();}@Overridepublic void chargeOnThreePin() {System.out.println("使用三腳插頭");charger.charge();}@Overridepublic void chargeOnThreePinHK() {System.out.println("使用港版三腳插頭");charger.charge();}}如果文章對(duì)您有所幫助, 請(qǐng)不吝點(diǎn)擊關(guān)注一下我的微信公眾號(hào):FSA全棧行動(dòng), 這將是對(duì)我最大的激勵(lì). 公眾號(hào)不僅有Android技術(shù), 還有iOS, Python等文章, 可能有你想要了解的技能知識(shí)點(diǎn)哦~
總結(jié)
以上是生活随笔為你收集整理的DesignPattern - 适配器模式【结构型】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 通信网络实验-嗅探器实现
- 下一篇: Shadow Volume DX8