国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

譯|調(diào)整JavaScript抽象的迭代方案

madthumb / 2164人閱讀

摘要:隨時(shí)調(diào)整模塊移除模塊。你該做什么在源代碼管理歷史記錄中找到舊的模塊。官網(wǎng)訪問官網(wǎng)更快閱讀全部免費(fèi)分享課程出品全網(wǎng)最新微信小程序基于最新版開發(fā)者工具之初中級培訓(xùn)教程分享出品基于搭建實(shí)戰(zhàn)項(xiàng)目教程包含文章視頻源代碼

原文作者:Kaloyan Kosev

原文鏈接:https://css-tricks.com/adapting-javascript-abstractions-time/

翻譯譯者:小溪里

校對:華翔、小冬

即使還沒有讀過我的文章《在處理網(wǎng)絡(luò)數(shù)據(jù)的 JavaScript 抽象的重要性》,你也很有可能已經(jīng)意識到代碼的可維護(hù)性和可擴(kuò)展性很重要,這也是介紹 JavaScript 抽象的目的。

為了更加清楚的說明,我們假設(shè)在 JavaScript 中抽象是一個(gè)模塊。

一個(gè)模塊的最初實(shí)現(xiàn)只是它們漫長(也許是持久的)的生命周期過程的開始。我將一個(gè)模塊的生命周期分成 3 個(gè)重要階段。

引入模塊。在項(xiàng)目中編寫該模塊或復(fù)用該模塊;

調(diào)整模塊。隨時(shí)調(diào)整模塊;

移除模塊。

在我先前的文章中,重心放在了第一點(diǎn)上。而在這篇文章中,我將把重點(diǎn)放在第二點(diǎn)上。

模塊更改是我經(jīng)常碰到的一個(gè)難題。與引入模塊相比,開發(fā)者維護(hù)和更改模塊的方式對保證項(xiàng)目的可維護(hù)性和可拓展性是同等重要甚至是更加重要。我看過一個(gè)寫得很好、抽象得很好的模塊隨著時(shí)間推移歷經(jīng)多次更改后被徹底毀了。我自己也經(jīng)常是造成那種破壞性更改的其中一個(gè)。

當(dāng)我說破壞性,我指的是對可維護(hù)性和可擴(kuò)展性方面的破壞。我也明白,當(dāng)面臨項(xiàng)目最后交付期限的壓力時(shí),放慢速度以進(jìn)行更好的修改設(shè)計(jì)并不是優(yōu)先選擇。

開發(fā)者做出非最優(yōu)修改的原因可能有很多種,我在這里想特別強(qiáng)調(diào)一個(gè):

以可維護(hù)的方式進(jìn)行修改的技巧

這種方法讓你的修改顯得更專業(yè)。

讓我們從一個(gè) API 模塊的代碼示例開始。之所以選擇這個(gè)示例,是因?yàn)榕c外部 API 通信是我在開始項(xiàng)目時(shí)定義的最基本的抽象之一。這里的想法是將所有與 API 相關(guān)的配置和設(shè)置(如基本 URL,錯(cuò)誤處理邏輯等)存儲在這個(gè)模塊中.

我將編寫一個(gè)設(shè)置 API.url、一個(gè)私有方法 API._handleError() 和一個(gè)公共方法 API.get():

class API {
  constructor() {
    this.url = "http://whatever.api/v1/";
  }

  /**
   * API 數(shù)據(jù)獲取的特有方法
   * 檢查一個(gè) HTTP 返回的狀態(tài)碼是否在成功的范圍內(nèi)
   */
  _handleError(_res) {
    return _res.ok ? _res : Promise.reject(_res.statusText);
  }

  /**
   * 獲取數(shù)據(jù)
   * @return {Promise}
   */
  get(_endpoint) {
    return window.fetch(this.url + _endpoint, { method: "GET" })
      .then(this._handleError)
      .then( res => res.json())
      .catch( error => {
        alert("So sad. There was an error.");
        throw new Error(error);
      });
  }
};

在這個(gè)模塊中,公共方法 API.get() 返回一個(gè) Promise。我們使用我們抽象出來的 API模塊,而不是通過 window.fetch() 直接調(diào)用 Fetch API 。例如,獲取用戶信息 API.get("user")或當(dāng)前天氣預(yù)報(bào) API.get("weather")。實(shí)現(xiàn)這個(gè)功能的重要意義在于Fetch API與我們的代碼沒有緊密耦合。

現(xiàn)在,我們面臨一個(gè)修改!技術(shù)主管要求我們把獲取遠(yuǎn)程數(shù)據(jù)的方式切換到Axios上。我們該如何應(yīng)對呢?

在我們開始討論方法之前,我們先來總結(jié)一下什么是不變的,什么是需要修改的:

更改:在公共 API.get() 方法中

需要修改 axios()window.fetch()調(diào)用;需要再次返回一個(gè) Promise, 以保持接口的一致, 好在 Axios 是基于 Promise 的,太棒了!

服務(wù)器的響應(yīng)的是 JSON。通過 Fetch API 并通過鏈?zhǔn)秸{(diào)用 .then( res => res.json()) 語句來解析響應(yīng)的數(shù)據(jù)。使用 Axios,服務(wù)器響應(yīng)是在 data 屬性中,我們不需要解析它。因此,我們需要將.then語句改為.then(res => res.data)

更改:在私有 API._handleError 方法中:

在響應(yīng)對象中缺少 ok 布爾標(biāo)志,但是,還有 statusText 屬性。我們可以通過它來串起來,如果它的值是 OK,那么一切將沒什么問題(附注:在 Fetch APIOKtrue 與在 Axios 中的 statusTextOK 是不一樣的。但為了便于理解,為了不過于寬泛,不再引入任何高級錯(cuò)誤處理。)

不變之處:API.url 保持不變,我們會發(fā)現(xiàn)錯(cuò)誤并以愉快的方式提醒他們。

講解完畢!現(xiàn)在讓我們深入應(yīng)用這些修改的實(shí)際方法。

方法一:刪除代碼。編寫代碼。
class API {
  constructor() {
    this.url = "http://whatever.api/v1/"; // 一模一樣的
  }

  _handleError(_res) {
      // DELETE: return _res.ok ? _res : Promise.reject(_res.statusText);
      return _res.statusText === "OK" ? _res : Promise.reject(_res.statusText);
  }

  get(_endpoint) {
      // DELETE: return window.fetch(this.url + _endpoint, { method: "GET" })
      return axios.get(this.url + _endpoint)
          .then(this._handleError)
          // DELETE: .then( res => res.json())
          .then( res => res.data)
          .catch( error => {
              alert("So sad. There was an error.");
              throw new Error(error);
          });
  }
};

聽起來很合理。 提交、上傳、合并、完成。

不過,在某些情況下,這可能不是一個(gè)好主意。想象以下情景:在切換到 Axios 之后,你會發(fā)現(xiàn)有一個(gè)功能并不適用于 XMLHttpRequests( Axios 的獲取數(shù)據(jù)的方法),但之前使用 Fetch API 的新型瀏覽器工作得很好。我們現(xiàn)在該怎么辦?

我們的技術(shù)負(fù)責(zé)人說,讓我們使用舊的 API 實(shí)現(xiàn)這個(gè)特定的用例,并繼續(xù)在其他地方使用 Axios 。你該做什么?在源代碼管理歷史記錄中找到舊的 API 模塊。還原。在這里和那里添加 if 語句。這樣聽起來并不太友好。

必須有一個(gè)更容易,更易于維護(hù)和可擴(kuò)展的方式來進(jìn)行更改!那么,下面的就是。

方法二:重構(gòu)代碼,做適配!

重構(gòu)的需求馬上來了!讓我們重新開始,我們不再刪除代碼,而是讓我們在另一個(gè)抽象中移動 Fetch 的特定邏輯,這將作為所有 Fetch 特定的適配器(或包裝器)。

HEY!???對于那些熟悉適配器模式(也被稱為包裝模式)的人來說,是的,那正是我們前進(jìn)的方向!如果您對所有的細(xì)節(jié)感興趣,請參閱這里我的介紹。

如下所示:

步驟1

將跟 Fetch 相關(guān)的幾行代碼拿出來,多帶帶抽象為一個(gè)新的方法 FetchAdapter

class FetchAdapter {
  _handleError(_res) {
    return _res.ok ? _res : Promise.reject(_res.statusText);
  }

  get(_endpoint) {
    return window.fetch(_endpoint, { method: "GET" })
      .then(this._handleError)
      .then( res => res.json());
  }
};
步驟2

重構(gòu)API模塊,刪除 Fetch 相關(guān)代碼,其余代碼保持不變。添加 FetchAdapter 作為依賴(以某種方式):

class API {
  constructor(_adapter = new FetchAdapter()) {
    this.adapter = _adapter;

    this.url = "http://whatever.api/v1/";
  }

  get(_endpoint) {
    return this.adapter.get(_endpoint)
      .catch( error => {
        alert("So sad. There was an error.");
        throw new Error(error);
      });
  }
};

現(xiàn)在情況不一樣了!這種結(jié)構(gòu)能讓你處理各種不同的獲取數(shù)據(jù)的場景(適配器)改。最后一步,你猜對了!寫一個(gè) AxiosAdapter

const AxiosAdapter = {
  _handleError(_res) {
    return _res.statusText === "OK" ? _res : Promise.reject(_res.statusText);
  },

  get(_endpoint) {
    return axios.get(_endpoint)
      then(this._handleError)
      .then( res => res.data);
  }
};

API 模塊中,將默認(rèn)適配器改為 AxiosAdapter

class API {
  constructor(_adapter = new /*FetchAdapter()*/ AxiosAdapter()) {
    this.adapter = _adapter;

    /* ... */
  }
  /* ... */
};

真棒!如果我們需要在這個(gè)特定的用例中使用舊的 API 實(shí)現(xiàn),并且在其他地方繼續(xù)使用Axios?沒問題!

//不管你喜歡與否,將其導(dǎo)入你的模塊,因?yàn)檫@只是一個(gè)例子。
import API from "./API";
import FetchAdapter from "./FetchAdapter";

//使用 AxiosAdapter(默認(rèn)的)
const API = new API();
API.get("user");


// 使用FetchAdapter
const legacyAPI = new API(new FetchAdapter());
legacyAPI.get("user");

所以下次你需要改變你的項(xiàng)目時(shí),評估下面哪種方法更有意義:

刪除代碼,編寫代碼。

重構(gòu)代碼,寫適配器。

總結(jié)請根據(jù)你的場景選擇性使用。如果你的代碼庫濫用適配器和引入太多的抽象可能會導(dǎo)致復(fù)雜性增加,這也是不好的。

愉快的去使用適配器吧!

iKcamp原創(chuàng)新書《移動Web前端高效開發(fā)實(shí)戰(zhàn)》已在亞馬遜、京東、當(dāng)當(dāng)開售。

iKcamp官網(wǎng):https://www.ikcamp.com
訪問官網(wǎng)更快閱讀全部免費(fèi)分享課程:
《iKcamp出品|全網(wǎng)最新|微信小程序|基于最新版1.0開發(fā)者工具之初中級培訓(xùn)教程分享》
《iKcamp出品|基于Koa2搭建Node.js實(shí)戰(zhàn)項(xiàng)目教程》
包含:文章、視頻、源代碼

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/90274.html

相關(guān)文章

  • ()《學(xué)習(xí)JavaScript設(shè)計(jì)模式》(一)

    摘要:模式并不就是一個(gè)具體的解決方案。我們要記住模式的角色僅僅就是給我們提供一個(gè)解決方案體系。使用本地瀏覽器的方法比如來選擇所有為的元素。后者毫無競爭力。在本書的后面我們將繼續(xù)討論更多的設(shè)計(jì)模式。 原書鏈接Learning JavaScript Design Patterns水平有限很多地方不通順,錯(cuò)翻漏翻歡迎交流。 什么是模式? 模式是一種可普遍應(yīng)用于軟件設(shè)計(jì)——對我們前端人員來講就是Ja...

    ls0609 評論0 收藏0
  • 前端思考 - 收藏集 - 掘金

    摘要:并嘗試用為什么你統(tǒng)計(jì)的方式是錯(cuò)的掘金翻譯自工程師的文章。正如你期望的,文中的前端開發(fā)單一職責(zé)原則前端掘金單一職責(zé)原則又稱單一功能原則,面向?qū)ο笪鍌€(gè)基本原則之一。 單頁式應(yīng)用性能優(yōu)化 - 首屏數(shù)據(jù)漸進(jìn)式預(yù)加載 - 前端 - 掘金前言 針對首頁和部分頁面打開速度慢的問題,我們開始對單頁式應(yīng)用性能進(jìn)行優(yōu)化。本文介紹其中一個(gè)方案:基于 HTTP Chunk 的首屏數(shù)據(jù)漸進(jìn)式預(yù)加載方案,該方案總...

    LinkedME2016 評論0 收藏0
  • 6 款 Javascript 圖像處理庫

    摘要:運(yùn)行代碼的結(jié)果如下是大名鼎鼎的并且非常權(quán)威的圖像處理庫。允許使用不同的媒介,用于創(chuàng)建動畫片,數(shù)字形象和數(shù)字藝術(shù),也可以用于圖像處理。從正面的角度看,他是一個(gè)可靈活調(diào)整以及一個(gè)很好的了解圖像處理算法的途徑。 文/ Tine譯/Mantra 附原文地址:http://blog.webkid.io/image-p... 如果你正在尋找更高效的辦法來處理或操縱你 web 項(xiàng)目中的圖片,那么這篇...

    muddyway 評論0 收藏0
  • [] TC39,ECMAScript 和 JavaScript 未來(Part 1)

    摘要:由很多令人興奮的功能,如對象的解析與剩余,異步迭代器,方法和更好的正則表達(dá)式支持。迭代可以是任何遵循迭代器協(xié)議的對象。迭代器方法應(yīng)該返回一個(gè)具有方法的對象。 原文:TC39, ECMAScript, and the Future of JavaScript作者:Nicolás Bevacqua 譯者序 很榮幸能夠和 Nicolás Bevacqua 同臺分享。Nicolás Beva...

    ziwenxie 評論0 收藏0
  • [] PureScript: 一門編JavaScript Haskell 方言

    摘要:原文是一門編譯到的強(qiáng)類型靜態(tài)類型語言它的功能受到的激發(fā)并且使用編寫其目標(biāo)是編譯到同時(shí)保持清潔跟可讀而且根據(jù)作者所說具備跟其他編譯到的語言相互操作的能力繼承了當(dāng)中一些突出的功能其中有類型推斷允許在任何可能的地方減少類型聲明的書寫一種類型構(gòu) 原文: http://www.infoq.com/news/2014/09/purescript-haskell-javascript PureS...

    陳江龍 評論0 收藏0

發(fā)表評論

0條評論

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