天天看點

JavaScript設計模式與實踐--擴充卡模式

擴充卡模式(Adapter)

擴充卡模式主要用來解決兩個已有接口之間不比對的問題,它不考慮這些接口是怎樣實作的,也不考慮它們将來可能會如何演化。擴充卡模式不需要改變已有的接口,就能夠使它們協同作用。

擴充卡的别名是包裝器(wrapper),這是一個相對簡單的模式。在程式開發中有許多這樣的場景:當我們試圖調用子產品或者對象的某個接口時,卻發現這個接口的格式并不符合目前的需求。這時候有兩種解決辦法,第一種是修改原來的接口實作,但如果原來的子產品很複雜,或者我們拿到的子產品是一段别人編寫的經過壓縮的代碼,修改原接口就顯得不太現實了。第二種辦法是建立一個擴充卡,将原接口轉換為客戶希望的另一個接口,客戶隻需要和擴充卡打交道。

現實中也有很多擴充卡的例子:電源插座,usb擴充卡等等;例如iPhone7以後的耳機接口從3.5mm圓孔接口更改成為了蘋果專屬的 lightning接口。許多人以前的圓孔耳機就需要下面的一個擴充卡,才能夠在自個兒新買的iPhone上面聽歌。

JavaScript設計模式與實踐--擴充卡模式

2. 擴充卡模式使用場景

2.1 接口适配

當我們向googleMap 和baiduMap都發出“顯示”請求時,googleMap和baiduMap` 分别以各自的方式在頁面中展現了地圖

JavaScript設計模式與實踐--擴充卡模式

這段程式得以順利運作的關鍵是googleMap 和baiduMap 提供了一緻的show 方法,但第三方的接口方法并不在我們自己的控制範圍之内,假如baiduMap 提供的顯示地圖的方法不叫show 而叫display 呢?

baiduMap 這個對象來源于第三方,正常情況下我們都不應該去改動它,而且有時候我們也改不了它。此時我們可以通過增加baiduMapAdapter 來解決問題:

JavaScript設計模式與實踐--擴充卡模式

2.2 參數的适配

有的情況下一個方法可能需要傳入多個參數,例如在做一些監控上報的SDK時,可能采集的資料比較多,這個類中有一個systemInfo,需要傳入五個參數用于接收手機的相關資訊:

JavaScript設計模式與實踐--擴充卡模式

通常在傳入的參數大于3的時候,我們就可以考慮将參數合并為一個對象的形式,就像我們$.ajax的做法一樣。下面我們可以将systemInfo的參數接口定義如下(String代表參數類型,?: 代表可選項)

JavaScript設計模式與實踐--擴充卡模式

可以看出,carrier、language,network這三個屬性不是必須傳入的,它們在方法内部可能被設定一些預設值。是以這個時候我們就可以在方法内部采用擴充卡來适配這個參數對象。這種方式在我們的插件或者npm包中是常見的;

JavaScript設計模式與實踐--擴充卡模式

2.3 資料的适配

資料的适配在前端中是最為常見的場景,這時擴充卡在解決前後端的資料依賴上有着重要的意義。通常伺服器端傳遞的資料和我們前端需要使用的資料格式是不一緻的,特别是在在使用一些UI架構時,架構所規定的資料有着固定的格式。是以,這個時候我們就需要對後端的資料格式進行适配。

例如網頁中有一個使用Echarts折線圖對網站每周的uv,通常後端傳回的資料格式如下所示:

JavaScript設計模式與實踐--擴充卡模式

但是Echarts需要的x軸的資料格式和坐标點的資料是長下面這樣的:

JavaScript設計模式與實踐--擴充卡模式

是以這是我們就可以使用一個擴充卡,将後端的傳回資料做适配:

JavaScript設計模式與實踐--擴充卡模式

3 總結

擴充卡模式是一對相對簡單的模式。但擴充卡模式在JS中的使用場景很多,在參數的适配上,有許多庫和架構都使用擴充卡模式;資料的适配在解決前後端資料依賴上十分重要。我們要認識到的是擴充卡模式本質上是一個”亡羊補牢”的模式,它解決的是現存的兩個接口之間不相容的問題,你不應該在軟體的初期開發階段就使用該模式;如果在設計之初我們就能夠統籌的規劃好接口的一緻性,那麼擴充卡就應該盡量減少使用。

在JavaScript中的擴充卡更多應用于在對象之間,為了使對象可用,我們通常會将對象拆分并重新組裝,這樣就必須了解适配對象的内部結構,這也是和外觀模式的差別所在,當然是配資模式同樣解決了對象之間的耦合度,包裝的适配代碼增加了一些資源消耗,但這是微乎其微的。

感謝閱讀 喜歡小編文章的,可以點個訂閱,小編都會不停更新文章,分享前端學習知識,以及程式員員的趣事!

繼續閱讀