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

資訊專欄INFORMATION COLUMN

使用合適的設(shè)計模式一步步優(yōu)化前端代碼

alin / 850人閱讀

摘要:修改配置遠比修改源代碼要簡單的多。在年提出了種設(shè)計模式。常用的設(shè)計模式及設(shè)計原則可以參考下面的思維導(dǎo)圖。每種設(shè)計模式都有它的適應(yīng)場景,有的場景也會使用多種設(shè)計模式。包含文章視頻源代碼原創(chuàng)新書移動前端高效開發(fā)實戰(zhàn)已在亞馬遜京東當(dāng)當(dāng)開售。

作者:曉飛
本文原創(chuàng),轉(zhuǎn)載請注明作者及出處

在后端語言中,設(shè)計模式應(yīng)用的較為廣泛。如Spring中常見的工廠模式、裝飾者模式、單例模式、迭代器模式。但是在日常的前端開發(fā)中,設(shè)計模式使用的較少,或者大家的代碼已經(jīng)遵循了某某設(shè)計模式但是我們并不知道。常見的設(shè)計模式有23種,如果單純的按照模式名稱+名詞解釋的方式來寫這篇文章,可能太枯燥了或者很難理解記憶,所以我打算換一種方式。下面我們以一個例子開始我們今天的文章。

假設(shè)我們有一個這樣的需求:
let page = {
  init: ()=>{
    //此處(placeA)有很多業(yè)務(wù)代碼或者調(diào)用了很多page中的其他初始化函數(shù)
  },
  ....
};

現(xiàn)在業(yè)務(wù)迭代,需要我們在page.init()初始化代碼塊的最后增加一些功能,同時不影響原先的功能。按照正常的寫法,我們可能會像下面這樣寫:

let page = {
  init: ()=>{
    //placeA
    page.newFunction();
  },
  newFunction: ()=>{
    ...
  }
};

這樣寫是可以解決我們的需求,但是這樣的代碼是具有侵略性的,我們不得不在原先的代碼的合適位置新增我們需要的代碼。但我們思考一個問題,如果我們用了某個插件或者某個被ungly、minify之后的代碼呢,我們怎么在找到合適的位置添加我們需要的功能呢?大家可以先自己思考一下,再看下面的內(nèi)容。

首先我們先看解決方案,再思考其背后的東西。
//我們可以在Function的原型鏈上定義一個擴展函數(shù),以實現(xiàn)我們的需求。
Function.prototype.fnAfter = function(fn) {
  var _self = this;
  return function() {
    _self.apply(this, arguments);
    fn.apply(this, arguments);
  }
};

page.init  = (page.init || function() {}).fnAfter(function() {
  console.log("我們要追加的功能成功啦~");
});

page.init();

上面的代碼已經(jīng)能夠?qū)崿F(xiàn)我們的需要了,但是其實還是不夠好或者可以寫的更靈活一些。因為我希望可以可以做到像jquery的鏈?zhǔn)秸{(diào)用那樣,可以一直往后面追加新的功能。那么我們在上面代碼的基礎(chǔ)上再擴展下,其實很簡單,我們只要再Function.prototype.fnAfter中再返回自身就好了。

Function.prototype.fnAfter = function(fn) {
  var _self = this;
  return function() {
    var fnOrigin = _self.apply(this, arguments);
    fn.apply(this, arguments);
    return fnOrigin;
  }
};

其實上面的代碼寫法還是可以優(yōu)化的。比如:

//每次擴展的時候我們都需要這么寫
page.init  = (page.init || function() {}).fnAfter(function() {
  //...
});
//我們能不能再優(yōu)化下,比如容錯代碼 || function(){} 在一個地方統(tǒng)一處理  
//或者我們新建一個工廠函數(shù)來幫我們統(tǒng)一做這樣的事情,這里我們就不展開了,文章篇幅有限。
我們上面的擴展其實就是遵循的是面向?qū)ο蟪绦蛟O(shè)計中的開放-封閉原則(OCP)。官方對OCP的解釋是:軟件實體(類、模塊、函數(shù)...)應(yīng)該是可以擴展的,但是不可修改。設(shè)計模式中有很多模式都遵循了開發(fā)-封閉原則,比如:發(fā)布-訂閱者模式、模板方法模式、策略模式、代理模式。

有的時候我們通過擴展來提高代碼的靈活性并不能解決所有的場景需要,在不可避免發(fā)生修改的時候,我們可以通過增加配置文件,讓用戶修改配置文件以實現(xiàn)個性化需求也是合理的。修改配置遠比修改源代碼要簡單的多。

有了上面的引入,我們來看幾個前端開發(fā)中常見的設(shè)計模式。

單例模式

單例模式顧名思義:保證一個類僅有一個實例,  
并且對外暴露一個能夠訪問到它的訪問點。

實現(xiàn)單例模式的核心就是保證一個類僅有一個實例,那么意思就是當(dāng)創(chuàng)建一個對象時,我們需要判斷下之前有沒有創(chuàng)建過該實例,如果創(chuàng)建過則返回之前創(chuàng)建的實例,否則新建。

var fn = function() {
  this.instance = null;
};
fn.getInstance = function() {
  //寫法1
  if (!this.instance) {
    this.instance = new fn();
  }
  return this.instance;
  
  //寫法2
  return this.instance || (this.instance = new fn());
};

var fnA = fn.getInstance();
var fnB = fn.getInstance();
console.log(fnA === fnB); //true

日常的業(yè)務(wù)場景中,單例模式也比較常見,比如:一個頁面中的模態(tài)框只有一個,每次打開與關(guān)閉的都應(yīng)該是同一個,而不是重復(fù)新建。而且為了性能優(yōu)化,我們應(yīng)該在需要時再創(chuàng)建,而不是頁面初始化時就已經(jīng)存在于dom中,這個就是惰性單例模式

//假設(shè)我們需要點擊某個按鈕時就顯示出模態(tài)框,那么我們可以像下面這么實現(xiàn)。
var createModal = (function(){
  var modal = null;
  return function() {
    if (!modal) {
      modal = document.createElement("div");
      //...
      modal.style.display = "none";
      document.getElementById("container").append(modal);
    }
    return modal;
  }
})();

document.getElementById("showModal").click(function() {
  var modal = createModal();
  modal.style.display = "block";
});

上面的代碼中,我們將創(chuàng)建對象和管理實例的邏輯都放在一個地方,違反了單一職責(zé)原則,我們應(yīng)該多帶帶新建一個用于創(chuàng)建單例的方法,這樣我們不僅能創(chuàng)建唯一的modal實例,也能創(chuàng)建其他的,職責(zé)分開。

var createSingleInstance = function(fn) {
  var instance = null;
  return function() {
    if (!instance) {
      instance = fn.apply(this, arguments);
    }
    return instance;
  }
};

var createModal = function() {
  var modal = docuemnt.createElement("div");
  //...
  modal.style.display = "none";
  document.getElementById("container").append(modal);
  return modal;
};

var modal = createSingleInstance(createModal);

?

觀察者模式

定義了對象與其他對象之間的依賴關(guān)系,  
當(dāng)某個對象發(fā)生改變的時候,所有依賴到這個對象的地方都會被通知。

像knockout.js中的ko.compute以及vue中的computed函數(shù)其實就是這個模式的實踐。實現(xiàn)觀察者模式的核心就是我們需要有一個變量來保存所有的依賴,一個listen函數(shù)用于向變量中添加依賴,一個trigger函數(shù)用于觸發(fā)通知。

var observal = {
  eventObj: {},
  listen: function(key, fn) {
    this.eventObj[key] = this.eventObj[key] || [];
    this.eventObj[key].push(fn);
  },
  trigger: function(key) {
    var eventList = this.eventObj[key];
    if (!eventList || eventList.length < 1) {
      return;
    }
    var length = eventList.length;
    for (var i = 0; i < length; i++) {
      var event = eventList[i];
      event.apply(this, arguments);
    }
  }
};

//定義要監(jiān)聽的事件
observal.listen("command1", function() {
  console.log("黑夜給了我夜色的眼睛~");
});
observal.listen("command1", function() {
  console.log("我卻用它尋找光明~");
});
observal.listen("command2", function() {
  console.log("一花一世界~");
});
observal.listen("command2", function() {
  console.log("一碼一人生~");
});

//觸發(fā)某個監(jiān)聽的事件
observal.trigger("command1");//黑夜給了我夜色的眼睛~ 我卻用它尋找光明~
observal.trigger("command2");//一花一世界~ 一碼一人生~

使用觀察者模式(發(fā)布-訂閱模式)我們可以使得代碼更靈活、健壯性更高。訂閱者不需要了解消息來自哪一個發(fā)布者,發(fā)布者也不需要知道消息會發(fā)送給哪些訂閱者。

同樣的我們可以創(chuàng)建一個公用的函數(shù)庫,里面存放創(chuàng)建observal的工具方法,需要用到的地方我們就用這個方法創(chuàng)建一個發(fā)布訂閱對象。

其他設(shè)計模式及設(shè)計原則

設(shè)計模式有很多,這里篇幅有限就不再展開。GoF在1995年提出了23種設(shè)計模式。諸如策略者模式優(yōu)化表單驗證、代理模式、組合模式、裝飾者模式、適配器模式...這些后期可以再簡單探討或者大家后面自己了解。常用的設(shè)計模式及設(shè)計原則可以參考下面的思維導(dǎo)圖。

![常用設(shè)計模式](https://user-gold-cdn.xitu.io/2017/10/27/f7ab0664b5fd4e34dbb16eaab5813c9d)

![六大設(shè)計原則](https://user-gold-cdn.xitu.io/2017/10/27/038d561c77aba1ff095fa0c3cfc8c113)

看了上面的文章,相信大家對設(shè)計模式的好處有了直觀的了解,也大致掌握了單例模式及觀察者模式。

設(shè)計模式都是經(jīng)過了大量的代碼、軟件實踐而總結(jié)出來的優(yōu)秀的組織實踐方案。每種設(shè)計模式都有它的適應(yīng)場景,有的場景也會使用多種設(shè)計模式。只有了解了更多的設(shè)計模式,掌握各個設(shè)計模式自己的適應(yīng)場景,才能更好的為我們所用。

但是過早的優(yōu)化不一定是好事或者不是必須的,有時候我們可以一開始并不去優(yōu)化,等到某個應(yīng)用場景下出現(xiàn)了代碼組織混亂、需要額外擴展等問題,我們再優(yōu)化重構(gòu),以防過早優(yōu)化導(dǎo)致的不必要性或者只是增加了代碼不必要的復(fù)雜性。就像redux,如果一個頁面組件與組件之間有數(shù)據(jù)共享、需要在任意組件內(nèi)部拿到某個數(shù)據(jù)、任意一個組件中某個行為導(dǎo)致的數(shù)據(jù)變化需要通知到所有用到的地方,那么這個時候可以使用redux,一些簡單的表單頁面或者展示頁完全可以不用redux。

看到這里不容易,最后給大家講一個笑話輕松一下:
從前有只麋鹿,它在森林里玩兒,不小心走丟了。  
于是它給它的好朋友長頸鹿打電話:“喂…我迷路辣。”  
長頸鹿聽見了回答說:“喂~我長頸鹿辣~”

參考:曾探《javascript設(shè)計模式與開發(fā)實踐》

---

iKcamp官網(wǎng):http://www.ikcamp.com

訪問官網(wǎng)更快閱讀全部免費分享課程:《iKcamp出品|全網(wǎng)最新|微信小程序|基于最新版1.0開發(fā)者工具之初中級培訓(xùn)教程分享》。
包含:文章、視頻、源代碼

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

iKcamp最新活動

報名地址:http://www.huodongxing.com/ev...

“天天練口語”小程序總榜排名第四、教育類排名第一的研發(fā)團隊,面對面溝通交流。

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

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

相關(guān)文章

  • 前端每周清單第 34 期:Vue 現(xiàn)狀盤點與 3.0 展望,React 代碼遷移與優(yōu)化,圖片優(yōu)化詳論

    摘要:工程實踐立足實踐,提示實際水平內(nèi)聯(lián)函數(shù)與性能很多關(guān)于性能優(yōu)化的文章都會談及內(nèi)聯(lián)函數(shù),其也是常見的被詬病為拖慢性能表現(xiàn)的元兇之一不過本文卻是打破砂鍋問到底,論證了內(nèi)聯(lián)函數(shù)并不一定就會拖慢性能,過度的性能優(yōu)化反而會有損于應(yīng)用性能。 showImg(https://segmentfault.com/img/remote/1460000011481413?w=1240&h=825); 前端每周...

    CoderStudy 評論0 收藏0
  • 前端每周清單第 38 期: Node 9 發(fā)布,Kotlin 與 React,Netflix 架構(gòu)解

    摘要:發(fā)布本周正式發(fā)布,包含了一系列的特性提升與問題修復(fù),同時也在不斷致力于將打造地更為輕巧與高性能。當(dāng)然,姜振勇老師還會介紹的多種服務(wù),包括大數(shù)據(jù)網(wǎng)絡(luò)和安全,展現(xiàn)彈性安全和高可擴展性的全方位能力。 showImg(http://upload-images.jianshu.io/upload_images/1647496-2ce7598e6987d9af.jpg?imageMogr2/aut...

    Carbs 評論0 收藏0
  • 前端性能優(yōu)化

    摘要:端優(yōu)談?wù)勱P(guān)于前端的緩存的問題我們都知道對頁面進行緩存能夠有利于減少請求發(fā)送,從而達到對頁面的優(yōu)化。而作為一名有追求的前端,勢必要力所能及地優(yōu)化我們前端頁面的性能。這種方式主要解決了淺談前端中的過早優(yōu)化問題過早優(yōu)化是萬惡之源。 優(yōu)化向:單頁應(yīng)用多路由預(yù)渲染指南 Ajax 技術(shù)的出現(xiàn),讓我們的 Web 應(yīng)用能夠在不刷新的狀態(tài)下顯示不同頁面的內(nèi)容,這就是單頁應(yīng)用。在一個單頁應(yīng)用中,往往只有一...

    Dean 評論0 收藏0
  • 2017-10-29 前端日報

    摘要:作者眾成翻譯只寫的禪眾成翻譯如何使更高效如何用構(gòu)建前端架構(gòu)小米直達服務(wù)介紹與開發(fā)實戰(zhàn)搭建一個多頁面的無依賴的工程化項目掘金計算機網(wǎng)絡(luò)概念和結(jié)構(gòu)掘金英文 2017-10-29 前端日報 精選 【譯】圖與例解讀Async/AwaitVue + TypeScript 新項目起手式 React-Router動態(tài)路由設(shè)計最佳實踐Vue2 原理淺談使用合適的設(shè)計模式一步步優(yōu)化前端代碼The 14 ...

    hzx 評論0 收藏0
  • 前端每周清單第 51 期: React Context API 與模式變遷, Webpack 與 W

    摘要:前端每周清單第期與模式變遷與優(yōu)化界面生成作者王下邀月熊編輯徐川前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點分為新聞熱點開發(fā)教程工程實踐深度閱讀開源項目巔峰人生等欄目。 showImg(https://segmentfault.com/img/remote/1460000013279448); 前端每周清單第 51 期: React Context A...

    Jiavan 評論0 收藏0

發(fā)表評論

0條評論

alin

|高級講師

TA的文章

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