摘要:訂閱模式的一個(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
摘要:設(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)容,...
摘要:獨(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ù)中有一...
摘要:除此以外,讓元素脫離文檔流也是一個(gè)很好的方法。因?yàn)樵匾坏┟撾x文檔流,它對(duì)其他元素的影響幾乎為零,性能的損耗就能夠有效局限于一個(gè)較小的范圍。講完重排與重繪,往元素上綁定事件也是引起性能問(wèn)題的元兇。高性能這本書(shū)非常精致,內(nèi)容也非常豐富。 showImg(https://segmentfault.com/img/bVJgbt?w=600&h=784); 入手《高性能JavaScript》一...
摘要:最近閱讀了編寫(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)化...
摘要:盡管在類庫(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í)行它,比如:...
閱讀 1931·2021-09-22 15:23
閱讀 3414·2021-09-04 16:45
閱讀 2194·2021-07-29 14:49
閱讀 2830·2019-08-30 15:44
閱讀 1619·2019-08-29 16:36
閱讀 1151·2019-08-29 11:03
閱讀 1595·2019-08-26 13:53
閱讀 569·2019-08-26 11:57