Javascript 設計模式之介面卡模式

程式設計之上發表於2019-10-07

為什麼使用介面卡模式

專案經過多個版本迭代後,容易產生多物件(介面)相容問題,即多物件協同工作,而直接修改原物件會又不方便(會引發要修改更多的業務程式碼),這時可考慮用介面卡封裝,以便外部呼叫者統一使用。

定義

將一個類(物件)的介面(方法或屬性)轉化成使用者希望的另外一個介面(方法或屬性),使得原介面不相容的類(物件)可以正常使用。【即為相容而派生的 “轉換器”】。

生活用例

Javascript 設計模式之介面卡模式

實現

在不改變原有物件介面的基礎上,定義一個包裝物件,新物件呼叫原有介面,使外部呼叫者可以正常使用。

UML類圖

Javascript 設計模式之介面卡模式

程式碼

// 介面卡模式
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>
複製程式碼

設計原則驗證

  • 將舊介面和使用者進行分離(舊介面不做改變)
  • 符合開放封閉原則

你可以

目錄:Javascript 設計模式小書

上一篇:Javascript 設計模式之單例模式

文末

我的部落格

加我引進群

程式設計之上

相關文章