為什麼使用介面卡模式
專案經過多個版本迭代後,容易產生多物件(介面)相容問題,即多物件協同工作,而直接修改原物件會又不方便(會引發要修改更多的業務程式碼),這時可考慮用介面卡封裝,以便外部呼叫者統一使用。
定義
將一個類(物件)的介面(方法或屬性)轉化成使用者希望的另外一個介面(方法或屬性),使得原介面不相容的類(物件)可以正常使用。【即為相容而派生的 “轉換器”】。
生活用例
實現
在不改變原有物件介面的基礎上,定義一個包裝物件,新物件呼叫原有介面,使外部呼叫者可以正常使用。
UML類圖
程式碼
// 介面卡模式
class Adaptee {
do() {
return '原始插頭';
}
}
class Target {
constructor() {
this.adaptee = new Adaptee();
}
do() {
const info = this.adaptee.do();
return `可用插頭(轉換${info})`
}
}
const target = new Target();
console.log(target.do());
複製程式碼
場景
第三方 SDK 的應用
// 0.4.0/sdk.js
class AMap {
show() {
console.log('渲染高德地圖');
}
};
class BaiduMap {
display() {
console.log('渲染百度地圖');
}
};
// 對外都使用 show 方法,建立百度地圖適配
class BaiduMapAdapter extends BaiduMap {
constructor() {
super();
}
show() {
this.display();
}
};
// 外部呼叫,統一介面呼叫
const renderMap = map => {
map.show();
};
renderMap(new AMap());
renderMap(new BaiduMapAdapter());
複製程式碼
jQuery 使用
jQuery 封裝事件處理的介面卡,解決跨瀏覽器相容性問題。
// 0.4.0/jquery.on.js
// $('selector').on() 實現
const on = (target, event, callbacl) => {
if (target.addEventListener) {
// 標準事件監聽
target.addEventListener(event, callback);
} else if (target.attachEvent) {
// IE低版本事件監聽
target.attachEvent(event, callback);
} else {
// 低版本瀏覽器事件監聽
target[`on${event}`] = callback;
}
}
複製程式碼
ajax 封裝舊介面
// 現在封裝的方法
request({
url: '/getData',
type: 'POST',
dataType: 'json',
data: {}
}).done(funciton() { });
// 專案中已有程式碼
$.ajax({
// ...
});
// 問題來了,將 $.ajax 換成 request,難免會有一些問題
// 做一層介面卡
const $ = {
ajax: function(options) {
return request(options);
}
}
複製程式碼
vue computed
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vue computed</title>
</head>
<body>
<div id="app">
<p>順序:{{message}}</p>
<p>倒序:{{reversedMessage}}</p>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
message: '全杭州就你最帥'
},
computed: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
})
</script>
</body>
</html>
複製程式碼
設計原則驗證
- 將舊介面和使用者進行分離(舊介面不做改變)
- 符合開放封閉原則