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