成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

適配器在JavaScript中的體現

開發 前端
適配器設計模式在JavaScript中非常有用,在處理跨瀏覽器兼容問題、整合多個第三方SDK的調用,都可以看到它的身影。

適配器設計模式在JavaScript中非常有用,在處理跨瀏覽器兼容問題、整合多個第三方SDK的調用,都可以看到它的身影。

其實在日常開發中,很多時候會不經意間寫出符合某種設計模式的代碼,畢竟設計模式就是老前輩們總結提煉出來的一些能夠幫助提升開發效率的一些模版,源于日常的開發中。

而適配器其實在JavaScript中應該是比較常見的一種了。

在維基百科中,關于適配器模式的定義為:

在軟件工程中,適配器模式是一種軟件設計模式,允許從另一個接口使用現有類的接口。它通常用于使現有的類與其他類一起工作,而無需修改其源代碼。

生活中的例子

在生活中最常見的就是電源插頭的適配器了,世界各國的插座標準各不相同,如果需要根據各國的標準購買對應的電源插頭那未免太過于浪費錢財,如果說自己帶著插座,把人家墻敲碎,重新接線,也肯定是不現實的。

所以就會有插頭的適配器,用來將某種插頭轉換成另一種插頭,在插座和你的電源之間做中轉的這個東西,就是適配器。

[[245771]]

在代碼中的體現

而轉向到編程中,我個人是這樣理解的:

將那些你不愿意看見的臟代碼藏起來,你就可以說這是一個適配器

接入多個第三方SDK

舉個日常開發中的例子,我們在做一個微信公眾號開發,里邊用到了微信的支付模塊,經過長時間的聯調,終于跑通了整個流程,正當你準備開心的打包上線代碼的時候,得到了一個新需求:

我們需要接入支付寶公眾號的SDK,也要有支付的流程

為了復用代碼,我們可能會在腳本中寫下這樣的邏輯: 

  1. if (platform === 'wechat') {  
  2.   wx.pay(config)  
  3. } else if (platform === 'alipay') {  
  4.   alipay.pay(config)  
  5.  
  6. // 做一些后續的邏輯處理 

但是一般來說,各廠的SDK所提供的接口調用方式都會多多少少有些區別,雖說有些時候文檔可能用的是同一份,致敬友商。

所以針對上述的代碼可能是這樣的: 

  1. // 并不是真實的參數配置,僅僅舉例使用  
  2. const config = {  
  3.   price: 10,  
  4.   goodsId: 1  
  5.  
  6. // 還有可能返回值的處理方式也不相同  
  7. if (platform === 'wechat') {  
  8.   config.appId = 'XXX'  
  9.   config.secretKey = 'XXX'  
  10.   wx.pay(config).then((err, data) => {  
  11.     if (err) // error  
  12.     // success  
  13.   })  
  14. } else if (platform === 'alipay') {  
  15.   config.token = 'XXX'  
  16.   alipay.pay(config, data => {  
  17.     // success  
  18.   }, err => {  
  19.     // error  
  20.   })  

就目前來說,代碼接口還算是清晰,只要我們寫好注釋,這也不是一個太糟糕的代碼。

但是生活總是充滿了意外,我們又接到了需求需要添加QQ的SDK、美團的SDK、小米的SDK,或者某些銀行的SDK。

此時你的代碼可能是這樣的: 

  1. switch (platform) {  
  2.   case 'wechat':  
  3.     // 微信的處理邏輯  
  4.   break  
  5.   case 'QQ':  
  6.     // QQ的處理邏輯  
  7.   break  
  8.   case 'alipay':  
  9.     // 支付寶的處理邏輯  
  10.   break  
  11.   case 'meituan':  
  12.     // 美團的處理邏輯  
  13.   break  
  14.   case 'xiaomi':  
  15.     // 小米的處理邏輯  
  16.   break  

這已經不是一些注釋能夠彌補的問題了,這樣的代碼會變得越來越難維護,各種SDK千奇百怪的調用方式,如果其他人也要做類似的需求,還需要重新寫一遍這樣的代碼,那肯定是很浪費資源的一件事兒。

所以為了保證我們業務邏輯的清晰,同時也為了避免后人重復的踩這個坑,我們會將它進行拆分出來作為一個公共的函數來存在:

找到其中某一個SDK的調用方式或者一個我們約定好的規則作為基準。

我們來告訴調用方,你要怎么怎么做,你能怎樣獲取返回數據,然后我們在函數內部進行這些各種骯臟的判斷: 

  1. function pay ({  
  2.   price,  
  3.   goodsId  
  4. }) {  
  5.   return new Promise((resolve, reject) => {  
  6.     const config = {}  
  7.     switch (platform) {  
  8.       case 'wechat':  
  9.         // 微信的處理邏輯  
  10.         config.price = price  
  11.         config.goodsId = goodsId  
  12.         config.appId = 'XXX'  
  13.         config.secretKey = 'XXX'  
  14.         wx.pay(config).then((err, data) => {  
  15.           if (err) return reject(err)  
  16.           resolve(data)  
  17.         })  
  18.       break  
  19.       case 'QQ':  
  20.         // QQ的處理邏輯  
  21.         config.price = price * 100  
  22.         config.gid = goodsId  
  23.         config.appId = 'XXX'  
  24.         config.secretKey = 'XXX'  
  25.         config.success = resolve  
  26.         config.error = reject  
  27.         qq.pay(config)  
  28.       break  
  29.       case 'alipay':  
  30.         // 支付寶的處理邏輯  
  31.         config.payment = price  
  32.         config.id = goodsId  
  33.         config.token = 'XXX'  
  34.         alipay.pay(config, resolve, reject)  
  35.       break  
  36.     }  
  37.   })  

這樣無論我們在什么環境下,只要我們的適配器支持,就可以按照我們約定好的通用規則進行調用,而具體執行的是什么SDK,則是適配器需要關心的事情: 

  1. // run anywhere  
  2. await pay({  
  3.   price: 10,  
  4.   goodsId: 1  
  5. }) 

對于SDK提供方,僅僅需要知道自己所需要的一些參數,然后按照自己的方式進行數據返回。

對于SDK調用房,僅僅需要我們約定好的通用的參數,以及按照約定的方式進行監聽回調處理。

整合多個第三方SDK的任務就交由適配器來做,然后我們將適配器的代碼壓縮,混淆,放在一個看不見的角落里去,這樣的代碼邏輯就會變得很清晰了 :)。

適配器大致就是這樣的作用,有一點一定要明確,適配器不是銀彈,__那些繁瑣的代碼始終是存在的,只不過你在寫業務的時候看不到它罷了__,眼不見心不煩。

一些其他的例子

個人覺得,jQuery中就有很多適配器的例子,包括最基礎的$('selector').on,這個不就是一個很明顯的適配器模式么?

一步步的進行降級,并且抹平了一些瀏覽器之間的差異,讓我們可以通過簡單的on來進行在主流瀏覽器中進行事件監聽: 

  1. // 一個簡單的偽代碼示例  
  2. function on (target, event, callback) {  
  3.   if (target.addEventListener) {  
  4.     // 標準的監聽事件方式  
  5.     target.addEventListener(event, callback)  
  6.   } else if (target.attachEvent) {  
  7.     // IE低版本的監聽方式  
  8.     target.attachEvent(event, callback)  
  9.   } else {  
  10.     // 一些低版本的瀏覽器監聽事件方式  
  11.     target[`on${event}`] = callback  
  12.   }  

或者在Node中的這樣的例子更是常見,因為早年是沒有Promise的,所以大多數的異步由callback來完成,且有一個約定好的規則,Error-first callback: 

  1. const fs = require('fs')  
  2. fs.readFile('test.txt', (err, data) => {  
  3.   if (err) // 處理異常  
  4.   // 處理正確結果  
  5. }) 

而我們的新功能都采用了async/await的方式來進行,當我們需要復用一些老項目中的功能時,直接去修改老項目的代碼肯定是不可行的。

這樣的兼容處理需要調用方來做,所以為了讓邏輯代碼看起來不是太混亂,我們可能會將這樣的回調轉換為Promise的版本方便我們進行調用: 

  1. const fs = require('fs')  
  2. function readFile (fileName) {  
  3.   return new Promise((resolve, reject) => {  
  4.     fs.readFile(fileName, (err, data) => {  
  5.       if (err) reject(err)  
  6.       resolve(data)  
  7.     })  
  8.   })  
  9.  
  10. await readFile('test.txt') 

因為前邊也提到了,這種Error-first callback是一個約定好的形式,所以我們可以很輕松的實現一個通用的適配器: 

  1. function promisify(func) {  
  2.   return (...args) => new Promise((resolve, reject) => {  
  3.     func(...args, (err, data) => {  
  4.       if (err) reject(err)  
  5.       resolve(data)  
  6.     })  
  7.   })  

然后在使用前進行對應的轉換就可以用我們預期的方式來執行代碼: 

  1. const fs = require('fs')  
  2. const readFile = promisify(fs.readFile)  
  3. await readFile('test.txt') 

在Node8中,官方已經實現了類似這樣的工具函數:util.promisify 

小結

個人觀點:所有的設計模式都不是憑空想象出來的,肯定是在開發的過程中,總結提煉出的一些高效的方法,這也就意味著,可能你并不需要在剛開始的時候就去生啃這些各種命名高大上的設計模式。

因為書中所說的場景可能并不全面,也可能針對某些語言,會存在更好的解決辦法,所以生搬硬套可能并不會寫出有靈魂的代碼 :)

紙上得來終覺淺,絕知此事要躬行。 ———— 《冬夜讀書示子聿》,陸游 

責任編輯:龐桂玉 來源: 前端大全
相關推薦

2021-02-16 08:16:09

適配器模式MybatisJava

2012-09-19 15:29:26

Worklight適配器

2012-12-10 10:53:04

IBMdW

2025-06-05 01:45:00

Spring框架適配器

2015-08-07 10:05:37

recyclervie超省寫法

2012-04-12 09:33:02

JavaScript

2022-02-18 17:21:29

適配器模式客戶端

2020-10-25 08:56:21

適配器模式

2022-02-13 23:33:24

設計模式Java

2021-08-06 06:51:16

適配器配置Spring

2011-04-28 09:54:50

jQuery

2021-02-18 08:39:28

設計模式場景

2013-11-26 16:39:21

Android設計模式

2009-11-18 18:08:20

PHP適配器模式

2009-12-21 10:26:09

Oracle適配器

2012-05-16 17:22:11

Java設計模式

2012-08-02 10:46:34

JavaAdapter模式

2010-07-09 12:53:30

HART協議

2013-02-26 10:55:47

C#適配器設計模式

2014-12-17 09:57:01

AndroidAdapteViewHolder
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产91精品久久久久久久网曝门 | 久久精品二区亚洲w码 | 欧美精品一区二区三区在线 | 亚洲va欧美va天堂v国产综合 | 欧美一区二区三区在线观看 | 在线免费国产 | 日韩在线视频免费观看 | 久久青| 久久五月婷| 国产高清精品在线 | 欧美精品成人一区二区三区四区 | 婷婷丁香在线视频 | 久久久区| 精品91久久久 | 日韩三级电影一区二区 | 欧美中文字幕 | 日本在线看片 | 91精品国产乱码久久久久久久 | 91国语清晰打电话对白 | 九九精品网 | 日韩福利在线 | 久久久久亚洲 | 久草新视频 | 国产亚洲精品久久久优势 | 国产伦一区二区三区四区 | 国产精品国产精品 | 亚洲精品久久区二区三区蜜桃臀 | 精品视频导航 | 九九久久久久久 | 久久99精品久久 | av网站在线播放 | 看特级黄色片 | 99精品欧美一区二区蜜桃免费 | 国产 欧美 日韩 一区 | 色综合区 | 天堂一区 | 日韩精品视频在线 | 国产成人精品区一区二区不卡 | 成年人在线播放 | 久久高潮| 高清亚洲 |