<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JavaScript設(shè)計(jì)模式

          共 4289字,需瀏覽 9分鐘

           ·

          2020-04-09 23:24

          (給前端大學(xué)加星標(biāo),提升前端技能.

          作者:考拉海購前端團(tuán)隊(duì)

          https://juejin.im/post/59df4f74f265da430f311909

          設(shè)計(jì)模式的定義:在面向?qū)ο筌浖O(shè)計(jì)過程中針對(duì)特定問題的簡(jiǎn)潔而優(yōu)雅的解決方案
          當(dāng)然我們可以用一個(gè)通俗的說法:設(shè)計(jì)模式是解決某個(gè)特定場(chǎng)景下對(duì)某種問題的解決方案。因此,當(dāng)我們遇到合適的場(chǎng)景時(shí),我們可能會(huì)條件反射一樣自然而然想到符合這種場(chǎng)景的設(shè)計(jì)模式。比如,當(dāng)系統(tǒng)中某個(gè)接口的結(jié)構(gòu)已經(jīng)無法滿足我們現(xiàn)在的業(yè)務(wù)需求,但又不能改動(dòng)這個(gè)接口,因?yàn)榭赡茉瓉淼南到y(tǒng)很多功能都依賴于這個(gè)接口,改動(dòng)接口會(huì)牽扯到太多文件。因此應(yīng)對(duì)這種場(chǎng)景,我們可以很快地想到可以用適配器模式來解決這個(gè)問題。下面介紹幾種在JavaScript中常見的幾種設(shè)計(jì)模式:

          1、單例模式

          單例模式的定義:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。實(shí)現(xiàn)的方法為先判斷實(shí)例存在與否,如果存在則直接返回,如果不存在就創(chuàng)建了再返回,這就確保了一個(gè)類只有一個(gè)實(shí)例對(duì)象。適用場(chǎng)景:一個(gè)單一對(duì)象。比如:彈窗,無論點(diǎn)擊多少次,彈窗只應(yīng)該被創(chuàng)建一次。
          class CreateUser {    constructor(name) {        this.name = name;        this.getName();    }    getName() {         return this.name;    }}// 代理實(shí)現(xiàn)單例模式var ProxyMode = (function() {    var instance = null;    return function(name) {        if(!instance) {            instance = new CreateUser(name);        }        return instance;    }})();// 測(cè)試單體模式的實(shí)例var a = new ProxyMode("aaa");var b = new ProxyMode("bbb");// 因?yàn)閱误w模式是只實(shí)例化一次,所以下面的實(shí)例是相等的console.log(a === b);    //true

          2、策略模式

          策略模式的定義:定義一系列的算法,把他們一個(gè)個(gè)封裝起來,并且使他們可以相互替換。策略模式的目的就是將算法的使用算法的實(shí)現(xiàn)分離開來。一個(gè)基于策略模式的程序至少由兩部分組成。第一個(gè)部分是一組策略類(可變),策略類封裝了具體的算法,并負(fù)責(zé)具體的計(jì)算過程。第二個(gè)部分是環(huán)境類Context(不變),Context接受客戶的請(qǐng)求,隨后將請(qǐng)求委托給某一個(gè)策略類。要做到這一點(diǎn),說明Context中要維持對(duì)某個(gè)策略對(duì)象的引用。
          /*策略類*/var levelOBJ = {    "A": function(money) {        return money * 4;    },    "B" : function(money) {        return money * 3;    },    "C" : function(money) {        return money * 2;    } };/*環(huán)境類*/var calculateBouns =function(level,money) {    return levelOBJ[level](money);};console.log(calculateBouns('A',10000)); // 40000

          3、代理模式

          代理模式的定義:為一個(gè)對(duì)象提供一個(gè)代用品或占位符,以便控制對(duì)它的訪問。常用的虛擬代理形式:某一個(gè)花銷很大的操作,可以通過虛擬代理的方式延遲到這種需要它的時(shí)候才去創(chuàng)建(例:使用虛擬代理實(shí)現(xiàn)圖片懶加載)圖片懶加載的方式:先通過一張loading圖占位,然后通過異步的方式加載圖片,等圖片加載好了再把完成的圖片加載到img標(biāo)簽里面。
          var imgFunc = (function() {    var imgNode = document.createElement('img');    document.body.appendChild(imgNode);    return {        setSrc: function(src) {            imgNode.src = src;        }    }})();var proxyImage = (function() {    var img = new Image();    img.onload = function() {        imgFunc.setSrc(this.src);    }    return {        setSrc: function(src) {            imgFunc.setSrc('./loading,gif');            img.src = src;        }    }})();proxyImage.setSrc('./pic.png');
          使用代理模式實(shí)現(xiàn)圖片懶加載的優(yōu)點(diǎn)還有符合單一職責(zé)原則。減少一個(gè)類或方法的粒度和耦合度。

          4、中介者模式

          中介者模式的定義:通過一個(gè)中介者對(duì)象,其他所有的相關(guān)對(duì)象都通過該中介者對(duì)象來通信,而不是相互引用,當(dāng)其中的一個(gè)對(duì)象發(fā)生改變時(shí),只需要通知中介者對(duì)象即可。通過中介者模式可以解除對(duì)象與對(duì)象之間的緊耦合關(guān)系。例如:現(xiàn)實(shí)生活中,航線上的飛機(jī)只需要和機(jī)場(chǎng)的塔臺(tái)通信就能確定航線和飛行狀態(tài),而不需要和所有飛機(jī)通信。同時(shí)塔臺(tái)作為中介者,知道每架飛機(jī)的飛行狀態(tài),所以可以安排所有飛機(jī)的起降和航線安排。中介者模式適用的場(chǎng)景:例如購物車需求,存在商品選擇表單、顏色選擇表單、購買數(shù)量表單等等,都會(huì)觸發(fā)change事件,那么可以通過中介者來轉(zhuǎn)發(fā)處理這些事件,實(shí)現(xiàn)各個(gè)事件間的解耦,僅僅維護(hù)中介者對(duì)象即可。
          var goods = {   //手機(jī)庫存    'red|32G': 3,    'red|64G': 1,    'blue|32G': 7,    'blue|32G': 6,};//中介者var mediator = (function() {    var colorSelect = document.getElementById('colorSelect');    var memorySelect = document.getElementById('memorySelect');    var numSelect = document.getElementById('numSelect');    return {        changed: function(obj) {            switch(obj){                case colorSelect:                    //TODO                    break;                case memorySelect:                    //TODO                    break;                case numSelect:                    //TODO                    break;            }        }    }})();colorSelect.onchange = function() {    mediator.changed(this);};memorySelect.onchange = function() {    mediator.changed(this);};numSelect.onchange = function() {    mediator.changed(this);};

          5、裝飾者模式

          裝飾者模式的定義:在不改變對(duì)象自身的基礎(chǔ)上,在程序運(yùn)行期間給對(duì)象動(dòng)態(tài)地添加方法。例如:現(xiàn)有4種型號(hào)的自行車分別被定義成一個(gè)單獨(dú)的類,如果給每輛自行車都加上前燈、尾燈、鈴鐺這3個(gè)配件,如果用類繼承的方式,需要?jiǎng)?chuàng)建4*3=12個(gè)子類。但如果通過裝飾者模式,只需要?jiǎng)?chuàng)建3個(gè)類。裝飾者模式適用的場(chǎng)景:原有方法維持不變,在原有方法上再掛載其他方法來滿足現(xiàn)有需求;函數(shù)的解耦,將函數(shù)拆分成多個(gè)可復(fù)用的函數(shù),再將拆分出來的函數(shù)掛載到某個(gè)函數(shù)上,實(shí)現(xiàn)相同的效果但增強(qiáng)了復(fù)用性。例:用AOP裝飾函數(shù)實(shí)現(xiàn)裝飾者模式
          Function.prototype.before = function(beforefn) {    var self = this;    //保存原函數(shù)引用    return function(){  //返回包含了原函數(shù)和新函數(shù)的 '代理函數(shù)'        beforefn.apply(this, arguments);    //執(zhí)行新函數(shù),修正this        return self.apply(this,arguments);  //執(zhí)行原函數(shù)    }}Function.prototype.after = function(afterfn) {    var self = this;    return function(){        var ret = self.apply(this,arguments);        afterfn.apply(this, arguments);        return ret;    }}var func = function() {    console.log('2');}//func1和func3為掛載函數(shù)var func1 = function() {    console.log('1');}var func3 = function() {    console.log('3');}func = func.before(func1).after(func3);func();
          本文完~

          分享前端好文,點(diǎn)亮?在看?35d53626885dedede8b940054d0b66b2.webp

          瀏覽 41
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  翔田千里珍藏版无码 | 色老汉AV一区二区三区 | 被扒开腿猛进入爽爽A片软件 | 操逼在线网站观看 | www.A片 |