Javascript 設計模式之適配器模式

爲何使用適配器模式

項目通過多個版本迭代後,容易產生多對象(接口)兼容問題,即多對象協同工做,而直接修改原對象會又不方便(會引起要修改更多的業務代碼),這時可考慮用適配器封裝,以便外部調用者統一使用。javascript

定義

將一個類(對象)的接口(方法或屬性)轉化成使用者但願的另一個接口(方法或屬性),使得原接口不兼容的類(對象)能夠正常使用。【即爲兼容而派生的 「轉換器」】。css

生活用例

實現

在不改變原有對象接口的基礎上,定義一個包裝對象,新對象調用原有接口,使外部調用者能夠正常使用。html

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 封裝事件處理的適配器,解決跨瀏覽器兼容性問題。vue

// 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 設計模式小書java

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

關注公衆號

相關文章
相關標籤/搜索