JavaScript設計模式——適配器模式
- 2019 年 10 月 19 日
- 筆記
適配器模式是設計模式行為型模式中的一種模式;
定義:
適配器用來解決兩個已有介面之間不匹配的問題,它並不需要考慮介面是如何實現,也不用考慮將來該如何修改;適配器不需要修改已有介面,就可以使他們協同工作;
白話解釋:
你買了某種電器產品,準備帶回家好好感受該款產品的魅力;結果帶回家之後準備通電使用的時候,發現該產品僅支援兩孔插座,而你家裡的電源插座都是三孔插座;這個時候你總不能又跑去電器專賣店退貨吧;突然靈機一動,你想起來了家裡還有多功能電源插座,而多功能店員插座恰好就是三孔,於是你拿出你的多功能電源插座插上電源插座,再拿你電器產品的電源插座插在多功能插座上面的兩孔插座上,開始享受美滋滋的生活;這裡的多功能插座就是一個適配器;
程式碼實現:
var googleMap = { show: function(){ console.log( '開始渲染Google地圖' ); } }; var baiduMap = { show: function(){ console.log( '開始渲染百度地圖' ); } }; var renderMap = function( map ){ if ( map.show instanceof Function ){ map.show(); } }; renderMap( googleMap ); // 開始渲染Google地圖 renderMap( baiduMap ); // 開始渲染百度地圖
當然上面的程式碼是能夠正常運行的,這得益於這兩個對象中的參數名都是一樣的,所以才能夠正常的運行和顯示;
var googleMap = { show: function(){ console.log( '開始渲染Google地圖' ); } }; var baiduMap = { display: function(){ console.log( '開始渲染百度地圖' ); } };
突然有一天如果baiduMap的方法名改變了呢?那麼我們再跟上面一樣運行肯定是回會報錯的,因為baiduMap對象中已經沒有了show()這個方法了;
使用適配器模式來修改:
var googleMap = { show: function(){ console.log( '開始渲染Google地圖' ); } }; var baiduMap = { display: function(){ console.log( '開始渲染百度地圖' ); } }; var baiduMapAdapter = { show: function(){ return baiduMap.display(); } }; renderMap( googleMap ); // 開始渲染Google地圖 renderMap( baiduMapAdapter ); // 開始渲染百度地圖
在這段程式碼中適配器做的事情其實很簡單,就是創建了一個對象,添加了一個同名的show()方法,然後在適配器裡面調用了baiduMap.display()方法,這樣我們只需要在調用baiduMap的時候調用我們的適配器即可達到預期效果;
我們作為前端開發人員,對頁面上期待得到的數據和數據格式肯定是比較了解的,但是在前後端分離的開發模式中有的時候會遇到這種尷尬的處境:
我們都知道很多UI組件或者工具庫會按指定的數據格式進行渲染,但是這個時候後端是不知道的;所以可能介面出來的數據我們是不能直接正常的在頁面上渲染的,而此時老闆催促我們趕緊上線,而後端堅持認為數據格式沒問題,堅決不修改;這個時候我們可以通過適配器模式來前端格式化數據;
後端返回的json數據格式:
[ { "day": "周一", "uv": 6300 }, { "day": "周二", "uv": 7100 }, { "day": "周三", "uv": 4300 }, { "day": "周四", "uv": 3300 }, { "day": "周五", "uv": 8300 }, { "day": "周六", "uv": 9300 }, { "day": "周日", "uv": 11300 } ]
Echarts圖表圖形需要的數據格式:
["周二", "周二", "周三", "周四", "周五", "周六", "周日"] //x軸的數據 [6300. 7100, 4300, 3300, 8300, 9300, 11300] //坐標點的數據
雖然心裡苦,但還是要解決問題!使用適配器來解決:
//x軸適配器 function echartXAxisAdapter(res) { return res.map(item => item.day); } //坐標點適配器 function echartDataAdapter(res) { return res.map(item => item.uv); }
創建兩個函數分別對數據按照echarts所需要的數據格式進行格式化處理即可解決問題;這兩個方法其實就是一個適配器,把指定的數據丟進去即可按照指定規則輸出我們期待得到的數據格式;
總結:
個人認為適配器模式其實是一種亡羊補牢式的設計模式,如果在項目開發的開始階段我們就知道我們期待的數據格式或者方法名等,我們就可能永遠都用不到適配器模式;但是項目的迭代往往是不可預期的,當項目迭代之後數據格式或者方法名發生變化之後,我們通常可以使用適配器模式來進行適配解決;當然了,最好的解決辦法就是項目開發過程中前後端協商討論數據格式、文件名等程式碼規範,這樣是對項目的開發效率是會有很大的提升的;