設計模式(五):適配器模式


今天要講的設計模式堪稱人人都會,不是因為它太簡單,而是因為它太常見,它就是 適配器模式

這個玩意大家應該都認識,它是一個耳機轉接頭

假如你只有一個圓孔插頭的耳機,但是手機的音頻插口是type-c的,這時候你是沒辦法用耳機聽歌的

利用耳機轉接頭,就可以使用圓孔的插頭和type-c插口的手機來聽歌

在我們對接一個三方系統時,假如我們系統的接口規范和三方系統的接口規范不一樣,該怎么對接

接口規范不一致,導致我們不能和三方系統完成對接,必須修改其中一方的接口規范

但是,不管修改哪一方的接口規范都可能導致系統已有的功能不能正常使用

讓我們發揮想象,把我們系統比作是圓孔耳機,把三方系統比作是type-c插口的手機。我們只需要一個「耳機轉接頭」就可以完成兩個系統的對接,而且不需要修改任何一方的代碼

這里的「耳機轉接頭」的作用就是把我們系統的接口規范轉換成三方系統的接口規范,讓兩個系統都不需要修改代碼就可以完成無縫對接

仔細想想一下,在我們的實際工作中,是不是經常做「耳機轉接頭」這樣的工作

實際上,「耳機轉接頭」就是一個適配器,這就是一個簡單的「適配器模式」

系統間的調用會用到適配器模式,代碼直接的調用也會用到適配器模式

使用場景

在兩個功能間無法完成無縫對接,必須要修改其中一處功能,但是修改工作量較大或者擔心修改完造成已有功能無法使用時,可以考慮使用適配器模式

適配器模式的識別方法:「當一個方法的入參是一個對象,而返回值是另一個對象時,這個方法就是一個適配器模式」

比如,java中的 java.util.Arrays#asList()

這個方法的作用是把一個數組轉換成list集合。數組和list屬於兩個不同的類,沒辦法完成無縫轉換

這時候就需要這個方法來進行「適配」,它的入參是一個任意類型的數組對象,返回值是一個list對象,符合上面我們說的適配器模式的識別方法,所以這個方法就是一個適配器模式

實際案例

假如我們有一個接口,需要統計用戶最近購買的商品信息並返回給前台

查詢數據庫的方法已經封裝好,返回的數據格式如下

前台要求返回的數據格式如下

我們先來用代碼模擬一下從數據庫查詢數據的邏輯

這里需要一個實體類,用來對應數據庫查詢出來的數據

用代碼模擬從數據庫查詢出5條數據

再來模擬一下前台要求的數據格式

這里需要兩個實體類對應前台要求的數據格式

用代碼來模擬一下實際給前台返回數據的邏輯

從數據庫查詢出來的數據和前台要求的數據都用代碼模擬出來了,那么該怎么把從數據庫查詢出來的格式轉換成前台需要的格式?

也就是說要怎么把List<UserProductInfo>對象轉換成List<UserProductInfoRsp>對象?

修改查詢數據庫的方法邏輯顯然不合適,作為DAO層對所有業務提供通用的查詢數據庫的能力,修改后會導致其他調用該方法的業務報錯

修改前台數據格式也不合適,前台開發模式是一雲多端的模式,不可能讓所有端的前台都跟着修改代碼

所以,該適配器模式出場啦

我們需要定義一個方法,方法的入參是List<UserProductInfo>,方法的返回值是List<UserProductInfoRsp>,在這個方法中完成兩個對象的轉換

ps:該方法的業務邏輯稍微有點復雜,感興趣的同學可以看一下。不願意看也行,只看方法的入參和返回值也不影響對適配器模式的理解

這樣我們就用適配器模式完成了兩個對象的轉換,而且兩方的業務邏輯都不需要修改,堪稱“完美”

總結

適配器模式又被稱為包裝模式或封裝器模式

當兩個功能間無法完成無縫對接,必須要修改其中一處功能,但是修改工作量較大或者擔心修改完造成已有功能無法使用時,可以考慮使用適配器模式

「適配器模式的優點」

  • 解耦:適配器將兩個功能完全解耦,從而達到不需要修改任何一方的原有邏輯的目的
  • 提高代碼復用性:適配的兩方不需要修改任何邏輯,可以更專注自己本身的業務邏輯,對外提供更通用的能力,使代碼的復用性更好
  • 提高系統的擴展性:可以通過各種適配器,對已有的功能或系統進行適配,讓其能適應更多的場景,使自己的功能或系統擴展性更高

「適配器模式的缺點」

  • 造成系統結構混亂:過多的使用適配器,會造成系統過於龐大且混亂不利於系統維護

學會設計模式不是目的,理解設計模式隱含的設計思想才能無往不利

「技術需要沉淀,我們下期再見」

-- 以上內容來自公眾號「赫連小伍」,轉載請注明出處


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM