亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

《JavaScript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐》讀書(shū)筆記

Panda / 1828人閱讀

摘要:訂閱模式的一個(gè)典型的應(yīng)用就是后面會(huì)寫(xiě)一篇相關(guān)的讀書(shū)筆記。享元模式享元模式的核心思想是對(duì)象復(fù)用,減少對(duì)象數(shù)量,減少內(nèi)存開(kāi)銷。適配器模式對(duì)目標(biāo)函數(shù)進(jìn)行數(shù)據(jù)參數(shù)轉(zhuǎn)化,使其符合目標(biāo)函數(shù)所需要的格式。

設(shè)計(jì)模式 單例模式

JS的單例模式有別于傳統(tǒng)面向?qū)ο笳Z(yǔ)言的單例模式,js作為一門(mén)無(wú)類的語(yǔ)言。使用全局變量的模式來(lái)實(shí)現(xiàn)單例模式思想。js里面的單例又分為普通單例和惰性單例,惰性單例指的是只有這個(gè)實(shí)例在需要被創(chuàng)建的時(shí)候才會(huì)被創(chuàng)建,創(chuàng)建后將始終保持這一個(gè)實(shí)例。

var getSingle = function (fn) {
    var result;
    return function () {
        return result || (result = fn.apply(this, arguments));
    }
};
策略模式
定義:定義一系列的算法,把它們一個(gè)個(gè)的封裝起來(lái),并且使他們可以相互替換。

策略模式至少由兩部分組成:第一個(gè)部分是一組策略類,用來(lái)封裝具體的算法,并負(fù)責(zé)計(jì)算過(guò)程;第二個(gè)部分是環(huán)境類,用于接受請(qǐng)求,并把請(qǐng)求委托給某一個(gè)策略類。策略模式,顧名思義就是指封裝一組組特定的算法,這些算法目的相同,用來(lái)實(shí)現(xiàn)不同條件下的特定要求。使用策略模式的優(yōu)點(diǎn)在于邏輯復(fù)用,代碼干凈,減少多重條件判斷語(yǔ)句的使用。比如:

const strategies = {
    S: (salary) => {
        return salary * 4;
    },
    A: (salary) => {
        return salary * 3;
    },
    B: (salary) => {
        return salary * 2;
    }
}

const calculateBouns = (key, salary) => {
    return strategies[key] && strategies[key](salary);
}

calculateBouns("S", 10000);
代理模式 虛擬代理

虛擬代理在不改變?cè)泻瘮?shù)(對(duì)象)的方法結(jié)構(gòu)的前提下,定義新的對(duì)象,并且實(shí)現(xiàn)同樣的接口,給被代理函數(shù)賦予額外的行為與邏輯,做一些過(guò)濾、合并、預(yù)處理等操作。

var myImage = (function () {
    var imgNode = document.createElement("img");
    document.body.appendChild(imgNode);

    return function (src) {
        imgNode.src = src;
    }
})();

var proxyImage = (function () {
    var img = new Image;
    img.onload = function () {
        myImage(this.src);
    };

    return function (src) {
        myImage("loading.gif");
        img.src = src;
    };
})();
緩存代理
緩存代理可以為一些開(kāi)銷大的運(yùn)算結(jié)果提供暫時(shí)的緩存(適用純函數(shù)模式),在下次運(yùn)算時(shí),如果傳遞的參數(shù)和之前保持一致,則直接返回之前存儲(chǔ)的運(yùn)算結(jié)果。
var createProxyFactory = function (fn) {
    var cache = {};
    return function () {
        var args = Array.prototype.join.call(arguments, ",");
        if (args in cache) {
            return cache[args];
        }
        return cache[args] = fn.apply(this, arguments);
    }
}
迭代器模式

類似數(shù)組的遍歷...

發(fā)布訂閱模式

發(fā)布訂閱模式是一種典型的推模式,即主動(dòng)向用戶推送數(shù)據(jù)的方式。一般的函數(shù)調(diào)用都是拉模式,即用戶主動(dòng)獲取數(shù)據(jù)。訂閱模式的一個(gè)典型的應(yīng)用就是rxjs(后面會(huì)寫(xiě)一篇相關(guān)的讀書(shū)筆記)。書(shū)中給出了一個(gè)最終版的代碼,但也是存在一定的局限性,具體實(shí)現(xiàn)需要按需解決。

var Event = (function () {
    var global = this, Event, _default = "default";

    Event = function () {
        var _listen,
            _trigger,
            _remove,
            _slice = Array.prototype.slice,
            _shift = Array.prototype.shift,
            _unshift = Array.prototype.unshift,
            namespaceCache = {},
            _create,
            find,
            // each方法綁定函數(shù)作用域?yàn)楫?dāng)前數(shù)組項(xiàng)
            each = function (ary, fn) {
                var ret;
                for (var i = 0, l = ary.length; i < l; i++) {
                    var n = ary[i];
                    ret = fn.call(n, i, n);
                }
                return ret;
            };

        _listen = function (key, fn, cache) {
            if (!cache[key]) {
                cache[key] = [];
            }
            cache[key].push(fn);
        };

        _remove = function (key, cache, fn) {
            if (cache[key]) {
                if (fn) {
                    for (var i = cache[key].length; i >= 0; i--) {
                        if (cache[key][i] === fn) {
                            cache[key].splice(i, 1);
                        }
                    }
                } else {
                    cache[key] = [];
                }
            }
        };

        _trigger = function () {
            var cache = _shift.call(arguments),
                key = _shift.call(arguments),
                args = arguments,
                _self = this,
                ret,
                stack = cache[key];

            if (!stack || !stack.length) {
                return;
            }

            return each(stack, function () {
                return this.apply(_self, args);
            });
        };

        _create = function (namespace) {
            var namespace = namespace || _default;
            var cache = {},
            offlineStack = [],
            ret = {
                listen: function (key, fn, last) {
                    _listen(key, fn, cache);
                    if (offlineStack === null) {
                        return;
                    }
                    if (last === "last") {
                        offlineStack.length && offlineStack.pop()();
                    } else {
                        each(offlineStack, function () {
                            this();
                        });
                    }
                    offlineStack = null;
                },
                one: function (key, fn, last) {
                    _remove(key, cache);
                    this.listen(key, fn, last);
                },
                remove: function (key, fn) {
                    _remove(key, cache, fn);
                },
                trigger: function () {
                    var fn, args, _self = this;

                    _unshift.call(arguments, cache);
                    args = arguments;

                    fn = function () {
                        return _trigger.apply(_self, args);
                    };

                    if (offlineStack) {
                        return offlineStack.push(fn);
                    }

                    return fn();
                }
            };

            return namespace ?
                (namespaceCache[namespace] ? namespaceCache[namespace] : namespaceCache[namespace] = ret)
                    : ret;
        };

        return {
            create: _create,
            one: function (key, fn, last) {
                var event = this.create();
                event.one(key, fn, last);
            },
            remove: function (key, fn) {
                var event = this.create();
                event.remove(key, fn);
            },
            listen: function (key, fn, last) {
                var event = this.create();
                event.listen(key, fn, last);
            },
            trigger: function () {
                var event = this.create();
                event.trigger.apply(this, arguments);
            }
        };
    }();

    return Event;
})();
命令模式

定義一系列的算法,功能不同,將他們聚合成一個(gè)整體,作為命令接受者,再定義一個(gè)中間函數(shù),用來(lái)根據(jù)不同的指令調(diào)用接受者對(duì)象。而實(shí)際命令對(duì)象只需要來(lái)調(diào)用這個(gè)中間函數(shù)而無(wú)需直接和接受者交互。命令模式適用于邏輯撤銷邏輯回放的操作。

組合模式

在父子鏈的函數(shù)上面實(shí)現(xiàn)相同的接口,在函數(shù)調(diào)用層面接口保持一致,具體函數(shù)邏輯各自獨(dú)立。組合模式可以讓我們使用樹(shù)形方式創(chuàng)建對(duì)象的結(jié)構(gòu)。我們可以把相同的操作應(yīng)用在組合對(duì)象和單個(gè)對(duì)象上。

模板方法模式

定義一系列api執(zhí)行流程,相同部分由父函數(shù)實(shí)現(xiàn),不同部分api里面的具體操作交由傳入的函數(shù)決定。在js里面,會(huì)更多的去使用高階函數(shù)去替代。

享元模式

享元模式的核心思想是對(duì)象復(fù)用,減少對(duì)象數(shù)量,減少內(nèi)存開(kāi)銷。

職責(zé)鏈模式

職責(zé)鏈模式的核心思想是,一個(gè)函數(shù),分為兩個(gè)部分,一部分:在符合條件的情況下,處理業(yè)務(wù)并結(jié)束傳遞;另外一部分,不符合條件,將業(yè)務(wù)處理轉(zhuǎn)交給下一個(gè)函數(shù),至于下個(gè)函數(shù)是誰(shuí),通過(guò)傳遞參數(shù)或者暴露接口來(lái)決定,而不是在函數(shù)內(nèi)部寫(xiě)死。降低函數(shù)耦合性。
職責(zé)鏈的優(yōu)點(diǎn)是降低函數(shù)復(fù)雜度,缺點(diǎn)是過(guò)長(zhǎng)的職責(zé)鏈可能會(huì)造成多段代碼閑置??赡芎芏嘀虚g鏈只起到傳遞參數(shù)的作用,降低了性能。

中介者模式

一些相互關(guān)聯(lián)的對(duì)象,對(duì)象與對(duì)象之間隔絕聯(lián)系,并且創(chuàng)建一個(gè)中間對(duì)象,將這些對(duì)象之間的聯(lián)系與關(guān)聯(lián)放在中間對(duì)象里面來(lái)處理。減少代碼耦合。

裝飾者模式

裝飾者模式與代理模式類似,即在執(zhí)行目標(biāo)函數(shù)之前或者后進(jìn)行一些額外的操作,與代理模式的區(qū)別在于,裝飾者模式所做的操作不一定與目標(biāo)函數(shù)是一個(gè)類型的,所實(shí)現(xiàn)的功能也可能是千差萬(wàn)別的。

狀態(tài)模式
定義:允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變他它的行為,對(duì)象看起來(lái)似乎修改了它的類。  
狀態(tài)模式在其內(nèi)部包含了多種轉(zhuǎn)態(tài)對(duì)象,這些狀態(tài)對(duì)象有著相似的api,在調(diào)用這些api的時(shí)候,會(huì)動(dòng)態(tài)修改狀態(tài)模式的當(dāng)前狀態(tài)。從而是狀態(tài)類的同一個(gè)api做出不同的反應(yīng)。
適配器模式

對(duì)目標(biāo)函數(shù)進(jìn)行數(shù)據(jù)參數(shù)轉(zhuǎn)化,使其符合目標(biāo)函數(shù)所需要的格式。

設(shè)計(jì)原則 單一職責(zé)原則
一個(gè)對(duì)象只做一件事情。
最少知識(shí)原則
一個(gè)軟件實(shí)體應(yīng)當(dāng)盡可能少的與其他實(shí)體發(fā)生相互作用。
開(kāi)放-封閉原則
當(dāng)需要改變一個(gè)程序的功能或者給這個(gè)程序增加新功能的時(shí)候,可以使用增加代碼的方式,但是不允許改動(dòng)程序的源代碼。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/97777.html

相關(guān)文章

  • JavaScript 設(shè)計(jì)模式開(kāi)發(fā)實(shí)踐讀書(shū)筆記

    摘要:設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐讀書(shū)筆記最近利用碎片時(shí)間在上面閱讀設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐讀書(shū)這本書(shū),剛開(kāi)始閱讀前兩章內(nèi)容,和大家分享下我覺(jué)得可以在項(xiàng)目中用的上的一些筆記。事件綁定暫時(shí)這么多,以后會(huì)不定期更新一些關(guān)于我讀這本書(shū)的筆記內(nèi)容 JavaScript 設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐讀書(shū)筆記 最近利用碎片時(shí)間在 Kindle 上面閱讀《JavaScript 設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐讀書(shū)》這本書(shū),剛開(kāi)始閱讀前兩章內(nèi)容,...

    FingerLiu 評(píng)論0 收藏0
  • 代碼書(shū)寫(xiě)優(yōu)化(javaScript設(shè)計(jì)模式開(kāi)發(fā)實(shí)踐--讀書(shū)筆記

    摘要:獨(dú)立出來(lái)的函數(shù)更加容易被改寫(xiě),減少維護(hù)成本。例如一個(gè)分頁(yè)函數(shù),函數(shù)接受一個(gè)表示挑戰(zhàn)頁(yè)碼,在跳轉(zhuǎn)前需要判斷是否在有效的取值范圍。面向?qū)ο笤O(shè)計(jì)鼓勵(lì)將行為分布在合理數(shù)量的更小對(duì)象之中。 這是《 javaScript設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐 》一書(shū)的最后一章代碼重構(gòu)。 以下的一些方法不是必須嚴(yán)格遵守的標(biāo)準(zhǔn),選擇實(shí)踐哪些,以及如何實(shí)現(xiàn)這都需根據(jù)情況而定(是不是有充足時(shí)間) 提煉函數(shù) 如果在函數(shù)中有一...

    geekidentity 評(píng)論0 收藏0
  • 《高性能JavaScript讀書(shū)筆記

    摘要:除此以外,讓元素脫離文檔流也是一個(gè)很好的方法。因?yàn)樵匾坏┟撾x文檔流,它對(duì)其他元素的影響幾乎為零,性能的損耗就能夠有效局限于一個(gè)較小的范圍。講完重排與重繪,往元素上綁定事件也是引起性能問(wèn)題的元兇。高性能這本書(shū)非常精致,內(nèi)容也非常豐富。 showImg(https://segmentfault.com/img/bVJgbt?w=600&h=784); 入手《高性能JavaScript》一...

    W_BinaryTree 評(píng)論0 收藏0
  • 《編寫(xiě)可維護(hù)的 JavaScript讀書(shū)筆記

    摘要:最近閱讀了編寫(xiě)可維護(hù)的,在這里記錄一下讀書(shū)筆記。禁止使用,,,的字符串形式。避免使用級(jí)事件處理函數(shù)。讓事件處理程序成為接觸到對(duì)象的唯一函數(shù)。檢測(cè)函數(shù)是檢測(cè)檢測(cè)函數(shù)的最佳選擇。為特定瀏覽器的特性進(jìn)行測(cè)試,并僅當(dāng)特性存在時(shí)即可應(yīng)用特性檢測(cè)。 最近閱讀了《編寫(xiě)可維護(hù)的 JavaScript》,在這里記錄一下讀書(shū)筆記。書(shū)中主要基于三個(gè)方向來(lái)講解怎么增加代碼的可維護(hù)性:編程風(fēng)格、編程實(shí)踐、自動(dòng)化...

    tuniutech 評(píng)論0 收藏0
  • javascript 的 eval()——編寫(xiě)可維護(hù)的javascript讀書(shū)筆記

    摘要:盡管在類庫(kù)中,可能會(huì)經(jīng)常用到通常和操作有關(guān),另外三種用法即使也非常罕見(jiàn)。一個(gè)通用的原則是,禁止使用,并且只在別無(wú)他法時(shí)使用,。和也是可以使用的,但不要用字符串形式而要用函數(shù) 再javascript中,eval()的參數(shù)是一個(gè)字符串,eval()會(huì)將傳入的字符串當(dāng)做代碼來(lái)執(zhí)行,開(kāi)發(fā)者可以通過(guò)這個(gè)函數(shù)來(lái)載入外部的javascript代碼,活著隨機(jī)生成Javascript代碼并執(zhí)行它,比如:...

    lemon 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<