javascript 設計模式之適配器模式

文章系列

javascript 設計模式之單例模式javascript

javascript 設計模式之適配器模式java

javascript 設計模式之裝飾者模式git

javascript設計模式之代理模式github

javascript 適配、代理、裝飾者模式的比較web

javascript 設計模式之狀態模式json

javascript 設計模式之迭代器模式設計模式

javascript 設計模式之策略模式瀏覽器

javascript 設計模式之觀察者模式markdown

javascript 設計模式之發佈訂閱者模式網絡

概念

適配器模式:將一個類(對象)的接口(方法或屬性)轉化成客戶但願的另一個接口(方法或屬性),使得本來因爲接口不兼容而不能一塊兒工做的那些類(對象)能夠正常協做。簡單理解就是爲兼容而生的 「轉換器」。

本文代碼

生活中的適配器

好比生活中去香港或國外,電源接口跟國內不一樣就須要一個轉換器 電源轉換器 再好比Type-c 轉接口,我以前用的耳機線都是圓頭的,直到最近買了個小米10 手機,發現它的手機孔居然是方形的,好在廠商有送了個轉換器,我才能繼續聽歌 耳機轉換器

比照上面的定義,

  • 類:小米10
  • 類的接口:方形
  • 客戶(我)
  • 另外一種接口:圓形

適配器的業務場景

插頭轉換器

class Adapter {
	specificRequest() {
		return '德國標準插頭'
	}
}
class Target {
	constructor() {
		this.adapter = new Adapter()
	}
	request() {
		let info = `${this.adapter.specificRequest()}---轉換成---中國插頭`
		return info
	}
}
let target = new Target()
console.info(target.request())

複製代碼

地圖接口之間的適配

var googleMap = {
	show: function () {
		// 方法是show
		console.log('開始渲染谷歌地圖')
	}
}
var baiduMap = {
	display: function () {
		//方法是display
		console.log('開始渲染百度地圖')
	}
}
var baiduMapAdapter = {
	show: function () {
		//適配器也改成show,返回的是display
		return baiduMap.display()
	}
}
//下面是渲染地圖的方法,傳入地圖對象
var renderMap = function (map) {
	//傳入地圖對象
	if (map.show instanceof Function) {
		//判斷
		map.show() //地圖對象的show方法
		//在傳入baiduMapAdapter對象的時候,調用show方法,返回的
		//實際是baiduMap的display方法。
	}
}

renderMap(googleMap) // 輸出:開始渲染谷歌地圖
renderMap(baiduMapAdapter) // 輸出:開始渲染百度地圖

複製代碼

兼容接口請求

export default class HttpUtils {
  // get方法
  static get(url) {
    return new Promise((resolve, reject) => {
      // 調用fetch
      fetch(url)
        .then(response => response.json())
        .then(result => {
          resolve(result)
        })
        .catch(error => {
          reject(error)
        })
    })
  }
  
  // post方法,data以object形式傳入
  static post(url, data) {
    return new Promise((resolve, reject) => {
      // 調用fetch
      fetch(url, {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        // 將object類型的數據格式化爲合法的body參數
        body: this.changeData(data)
      })
        .then(response => response.json())
        .then(result => {
          resolve(result)
        })
        .catch(error => {
          reject(error)
        })
    })
  }
  
  // body請求體的格式化方法
  static changeData(obj) {
    var prop,
      str = ''
    var i = 0
    for (prop in obj) {
      if (!prop) {
        return
      }
      if (i == 0) {
        str += prop + '=' + obj[prop]
      } else {
        str += '&' + prop + '=' + obj[prop]
      }
      i++
    }
    return str
  }
}
複製代碼

當想使用fetch 發起請求時,只須要按以下方式調用便可:

// 定義目標url地址
const URL = "xxxxx"
// 定義post入參
const params = {
    ...
}

// 發起post請求
 const postResponse = await HttpUtils.post(URL,params) || {}
 
 // 發起get請求
 const getResponse = await HttpUtils.get(URL)
複製代碼

但項目中難免有些舊的接口調用方式,好比有以下的:

// 發送get請求
Ajax('get', url地址, post入參, function(data){
    // 成功的回調邏輯
}, function(error){
    // 失敗的回調邏輯
})

複製代碼

爲了抹平差別,能夠採用適配器模式

// Ajax適配器函數,入參與舊接口保持一致
async function AjaxAdapter(type, url, data, success, failed) {
    const type = type.toUpperCase()
    let result
    try {
         // 實際的請求所有由新接口發起
         if(type === 'GET') {
            result = await HttpUtils.get(url) || {}
        } else if(type === 'POST') {
            result = await HttpUtils.post(url, data) || {}
        }
        // 假設請求成功對應的狀態碼是1
        result.statusCode === 1 && success ? success(result) : failed(result.statusCode)
    } catch(error) {
        // 捕捉網絡錯誤
        if(failed){
            failed(error.statusCode);
        }
    }
}

// 用適配器適配舊的Ajax方法
async function Ajax(type, url, data, success, failed) {
    await AjaxAdapter(type, url, data, success, failed)
}
複製代碼

如此一來,就用適配器 (AjaxAdapter) 去承接舊接口的參數,實現新舊接口的無縫對接。

使用適配器模式的場景

jQuery 中的應用

適配器模式很是適用於跨瀏覽器兼容,例如強大的 jQuery 封裝了事件處理的適配器,解決跨瀏覽器兼容性問題。

// $('selector').on 的實現
function on(target, event, callback) {
    if (target.addEventListener) {
        // 標準事件監聽
        target.addEventListener(event, callback);
    } else if (target.attachEvent) {
        // IE低版本事件監聽
        target.attachEvent(event, callback)
    } else {
        // 低版本瀏覽器事件監聽
        target[`on${event}`] = callback
    }
}
複製代碼

參考連接

JavaScript 設計模式核⼼原理與應⽤實踐

結語

你的點贊是對我最大的確定,若是以爲有幫助,請留下你的讚揚,謝謝!!!

相關文章
相關標籤/搜索