成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

從ES6重新認(rèn)識JavaScript設(shè)計模式(四): 適配器模式

URLOS / 1220人閱讀

摘要:什么是適配器模式適配器模式將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口,使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。中的適配器模式在前端項目中,適配器模式的使用場景一般有以下三種情況庫的適配參數(shù)的適配和數(shù)據(jù)的適配。

1 什么是適配器模式
適配器模式(Adapter):將一個類的接口轉(zhuǎn)換成客戶希望的另外一個接口,使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。

在生活中,我們有許多的適配器,例如iPhone7以后的耳機(jī)接口從3.5mm圓孔接口更改成為了蘋果專屬的 lightning接口。許多人以前的圓孔耳機(jī)就需要下面的一個適配器,才能夠在自個兒新買的iPhone上面聽歌。

在前端開發(fā)中,我們可能會遇見這樣的場景:當(dāng)我們試圖調(diào)用某個模塊或者對象的接口時,卻發(fā)現(xiàn)這個接口的格式不符合我們的需求。這時有兩種解決辦法:第一種是修改原來的接口實現(xiàn),但如果原來的代碼很復(fù)雜,例如是一個庫或框架,更改原代碼就顯得很不現(xiàn)實了。所以這時就需要使用今天所講的第二種辦法:創(chuàng)建一個適配器,將原接口轉(zhuǎn)換為客戶希望的另一個接口,客戶只需要使用適配器即可。

對于只有JavaScript這一門語言經(jīng)驗的前端開發(fā)來說,可能對于接口的概念比較陌生。建議參考閱讀TypeScript-接口的文檔來更好的理解接口。

2 ES6中的適配器模式

在前端項目中,適配器模式的使用場景一般有以下三種情況:庫的適配、參數(shù)的適配和數(shù)據(jù)的適配。下面我將以我在項目中的實際例子來說明。

2.1 庫的適配

項目上線前通常會要求前端開發(fā)者在頁面中會接入統(tǒng)計網(wǎng)頁數(shù)據(jù)用的SDK,這些SDK能夠采集用戶的信息和網(wǎng)頁行生成可視化的圖表和表格,來幫助網(wǎng)站運(yùn)營人員和產(chǎn)品經(jīng)理更好的根據(jù)用戶行為來提升網(wǎng)頁質(zhì)量。我們來看一下適配器在接入采集數(shù)據(jù)的庫時的使用場景:

目前國內(nèi)做得比較好的數(shù)據(jù)分析網(wǎng)站有百度統(tǒng)計、神策數(shù)據(jù)、友盟等。在一個你做的電商類網(wǎng)站 項目上線前,你的產(chǎn)品經(jīng)理要求你接入了百度的代碼用于數(shù)據(jù)采集,并在幾十個涉及用戶操作的地方進(jìn)行了埋點(diǎn)。百度統(tǒng)計提供的埋點(diǎn)接口格式如下:

 _hmt.push(["_trackEvent", category, action, opt_label,opt_value]);

按照產(chǎn)品經(jīng)理的要求,你根據(jù)上面的格式將埋點(diǎn)代碼寫到了頁面的多個地方:

//index.html
_hmt.push(["_trackEvent", "web", "page_enter", "position", "index.html"]);

//product-detail.html
_hmt.push(["_trackEvent", "web", "page_enter", "position", "product-detail.html"]);

_hmt.push(["_trackEvent", "web", "product_detail_view", "product_id", productId]);

_hmt.push(["_trackEvent", "web", "add-product-chart", "product_id", productId]);

//...還有幾十個頁面

過了幾個月之后,該電商網(wǎng)站發(fā)展速度很快,運(yùn)營人員感覺到百度統(tǒng)計提供的采集數(shù)據(jù)在已經(jīng)無法滿足當(dāng)前網(wǎng)站的規(guī)模。運(yùn)營人員和產(chǎn)品經(jīng)理商量后決定,數(shù)據(jù)采集平臺需要從百度統(tǒng)計切換到神策數(shù)據(jù),神策數(shù)據(jù)提供的埋點(diǎn)接口格式如下:

sa.track(eventName, {
  attrName: value 
})

接口的規(guī)則不同,就意味著你需要將幾十個百度統(tǒng)計的_htm.push接口更改成為神策提供的sa.track接口。其實不用這么麻煩,寫一個適配器就可以完成所有埋點(diǎn)事件的遷移:

//app.js

let _hmt = {
  push: (arr) {
    
    const [eventName, attrName, value] = [...arr.splice(2)];
    
    let attrObj = {
      [attrName]: value
    };

    sa.track(eventName, attrObj);
  }
}

通過分析比較百度統(tǒng)計的接口和神策的接口,可以知道在神策中只需要傳入三個參數(shù),eventName對應(yīng)的是百度統(tǒng)計接口中的action, attrName對應(yīng)的是百度統(tǒng)計接口中的opt_label, value對應(yīng)的是百度統(tǒng)計接口中的opt_value; 刪除了百度統(tǒng)計的SDK后,SDK所提供的_htm這個全局變量也就不存在了,我們可以利用該變量名做適配器,在push方法獲取sa.track所需要的三個參數(shù)并調(diào)用sa.track即可。

2.2 參數(shù)的適配

有的情況下一個方法可能需要傳入多個參數(shù),例如在SDK這個類中有一個phoneStatus,需要傳入五個參數(shù)用于接收手機(jī)的相關(guān)信息:

class SDK {
  phoneStatus(brand, os, carrier, language, network) {

    //dosomething.....
  }
}

通常在傳入的參數(shù)大于3的時候,我們就可以考慮將參數(shù)合并為一個對象的形式,就像我們$.ajax的做法一樣。下面我們可以將phoneStatus的參數(shù)接口定義如下(String代表參數(shù)類型,?: 代表可選項)

{
  brand: String
  os: String
  carrier:? String
  language:? String
  network:? String
}

可以看出,carrierlanguage,network這三個屬性不是必須傳入的,它們在方法內(nèi)部可能被設(shè)置一些默認(rèn)值。所以這個時候我們就可以在方法內(nèi)部采用適配器來適配這個參數(shù)對象。

class SDK {
  phoneStatus(config) {
    
    let defaultConfig = {
      brand: null,  //手機(jī)品牌
      os: null, //系統(tǒng)類型: Andoird或 iOS
      carrier: "china-mobile", //運(yùn)營商,默認(rèn)中國移動
      language: "zh", //語言類型,默認(rèn)中文
      network: "wifi", //網(wǎng)絡(luò)類型,默認(rèn)wifi
    }
    
    //參數(shù)適配
    for( let i in config) {
      defaultConfig[i] = config[i] || defaultConfig[i];
    }
    
    //dosomething.....
  }
}
2.3 數(shù)據(jù)的適配

數(shù)據(jù)的適配在前端中是最為常見的場景,這時適配器在解決前后端的數(shù)據(jù)依賴上有著重要的意義。通常服務(wù)器端傳遞的數(shù)據(jù)和我們前端需要使用的數(shù)據(jù)格式是不一致的,特別是在在使用一些UI框架時,框架所規(guī)定的數(shù)據(jù)有著固定的格式。所以,這個時候我們就需要對后端的數(shù)據(jù)格式進(jìn)行適配。

例如網(wǎng)頁中有一個使用Echarts折線圖對網(wǎng)站每周的uv,通常后端返回的數(shù)據(jù)格式如下所示:

[
  {
    "day": "周一",
    "uv": 6300
  },
  {
    "day": "周二",
    "uv": 7100
  },  {
    "day": "周三",
    "uv": 4300
  },  {
    "day": "周四",
    "uv": 3300
  },  {
    "day": "周五",
    "uv": 8300
  },  {
    "day": "周六",
    "uv": 9300
  }, {
    "day": "周日",
    "uv": 11300
  }
]

但是Echarts需要的x軸的數(shù)據(jù)格式和坐標(biāo)點(diǎn)的數(shù)據(jù)是長下面這樣的:

["周二", "周二", "周三", "周四", "周五", "周六", "周日"] //x軸的數(shù)據(jù)

[6300. 7100, 4300, 3300, 8300, 9300, 11300] //坐標(biāo)點(diǎn)的數(shù)據(jù)

所以這是我們就可以使用一個適配器,將后端的返回數(shù)據(jù)做適配:

//x軸適配器
function echartXAxisAdapter(res) {
  return res.map(item => item.day);
}

//坐標(biāo)點(diǎn)適配器
function echartDataAdapter(res) {
  return res.map(item => item.uv);
}
3 總結(jié)

適配器模式在JS中的使用場景很多,在參數(shù)的適配上,有許多庫和框架都使用適配器模式;數(shù)據(jù)的適配在解決前后端數(shù)據(jù)依賴上十分重要。但是適配器模式本質(zhì)上是一個亡羊補(bǔ)牢的模式,它解決的是現(xiàn)存的兩個接口之間不兼容的問題,你不應(yīng)該在軟件的初期開發(fā)階段就使用該模式;如果在設(shè)計之初我們就能夠統(tǒng)籌的規(guī)劃好接口的一致性,那么適配器就應(yīng)該盡量減少使用。

參考文獻(xiàn):

[1] 張榮銘 JavaScript設(shè)計模式 [M].人民郵電出版社

[2] 程杰 大話設(shè)計模式 [M].清華大學(xué)出版社

[3] 曾探 JavaScript設(shè)計模式與開發(fā)實踐 [M].r人民郵電出版社

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/95930.html

相關(guān)文章

  • ES6重新認(rèn)識JavaScript設(shè)計模式(三): 建造者模式

    摘要:書籍建造者類調(diào)用建造者高效能人士的七個習(xí)慣史蒂芬柯維勵志上面的這個類和第一個例子的效果一樣,但是長度確減少不少,在有更多屬性的時候,減少的代碼量會更為明顯。參考內(nèi)容設(shè)計模式張容銘 showImg(https://segmentfault.com/img/remote/1460000015147692); 1 什么是建造者模式? 建造者模式(Builder)是將一個復(fù)雜對象的構(gòu)建層與其表...

    hatlonely 評論0 收藏0
  • ES6重新認(rèn)識JavaScript設(shè)計模式(三): 建造者模式

    摘要:書籍建造者類調(diào)用建造者高效能人士的七個習(xí)慣史蒂芬柯維勵志上面的這個類和第一個例子的效果一樣,但是長度確減少不少,在有更多屬性的時候,減少的代碼量會更為明顯。參考內(nèi)容設(shè)計模式張容銘 showImg(https://segmentfault.com/img/remote/1460000015147692); 1 什么是建造者模式? 建造者模式(Builder)是將一個復(fù)雜對象的構(gòu)建層與其表...

    yuanxin 評論0 收藏0
  • ES6重新認(rèn)識JavaScript設(shè)計模式(一): 單例模式

    摘要:什么是單例模式單例模式是一種十分常用但卻相對而言比較簡單的單例模式。對象就是單例模式的體現(xiàn)??偨Y(jié)單例模式雖然簡單,但是在項目中的應(yīng)用場景卻是相當(dāng)多的,單例模式的核心是確保只有一個實例,并提供全局訪問。 1. 什么是單例模式? 單例模式是一種十分常用但卻相對而言比較簡單的單例模式。它是指在一個類只能有一個實例,即使多次實例化該類,也只返回第一次實例化后的實例對象。單例模式不僅能減少不必要...

    G9YH 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<