摘要:模式迭代器模式顧名思義,迭代器可以將對于一個聚合對象內(nèi)部元素的訪問與業(yè)務(wù)邏輯分離開。模式組合模式組合模式將對象組合成樹形結(jié)構(gòu),以表示層級結(jié)構(gòu)。重點是,葉結(jié)點與中間結(jié)點有統(tǒng)一借口。本文總結(jié)自設(shè)計模式與開發(fā)實踐,曾探著
模式1 - 單例模式
單例模式的核心是確保只有一個實例,并且提供全局訪問。
特點:
滿足“單一職責(zé)原則” : 使用代理模式,不在構(gòu)造函數(shù)中判斷是否已經(jīng)創(chuàng)建過該單例;
滿足惰性原則
應(yīng)用:
彈出登陸窗口。
實例:
var getSingle = function (fn) { var res; return function() { return res || (res = fn.apply(this, arguments)); } } var createPopup() { var div = document.createElement("div"); div.innerHTML = "Login window"; div.style.display = "none"; document.body.appendChild(div); return div; } var createLoginPopup = getSingle(createPopup); //create popup div here by using a given function, 滿足兩個原則 document.getElementById("loginBt").onclick = function() { var popup = createLoginPopup(); pop.style.display = "block"; }
模式2 - 策略模式
定義一個個可以相互替換的算法,并且把他們封裝起來。
特點:
符合開放-封閉原則 : 要修改使用的算法時不用深入函數(shù)內(nèi)部進(jìn)行修改,只需修改策略類;
將算法的實現(xiàn)與使用分離開,提高算法復(fù)用性;
通過組合、委托和多態(tài)避免多重條件選擇語句;
應(yīng)用:
動畫實現(xiàn)不同的緩動效果。
一般分為兩個部分:策略類于環(huán)境類。策略類用于封裝各種算法,并且負(fù)責(zé)具體的計算過程; 環(huán)境類負(fù)責(zé)接收用戶的請求,并且把請求委托給某一個策略類。因為各個策略類實現(xiàn)的算法和計算的結(jié)果不同,而環(huán)境類調(diào)用策略類的方法卻是相同的,這就體現(xiàn)了多態(tài)性。要想實現(xiàn)不同的算法,只需要替換環(huán)境類中的策略類即可。
在js中,我們不必構(gòu)造策略類,可直接使用函數(shù)作為策略對象。
示例:
var strategies = { "s1": function() { //algo 1 }, "s2": function() { //algo 2 }, "s3": function() { //algo 3 } } var someContext = new SomeConext(); someContext.start("s1"); //using s1 to calculate //someContext.add("s1"); or add s1 as a rule for validation
模式3 - 代理模式
代理就像一個經(jīng)紀(jì)人,當(dāng)用戶不方便直接訪問某個對象或者需要對訪問進(jìn)行一些過濾/加工時,可以通過代理來進(jìn)行對象訪問。代理會對請求進(jìn)行一些處理,然后再將請求傳遞給本體。
一般分為保護(hù)代理和虛擬代理:
保護(hù)代理負(fù)責(zé)過濾掉一些請求;
虛擬代理則是將一些花銷比較大的操作延遲到真正他的時候再去創(chuàng)建,例如new一個對象。
特點:
保證對象符合單一職責(zé)原則;
應(yīng)用:
圖片預(yù)加載, 合并http請求, 惰性加載, 緩存代理(避免重復(fù)計算,可以寫一個通用的緩存對象(其實就是一個閉包),將高階函數(shù)作為參數(shù)傳入)。
模式4 - 迭代器模式
顧名思義,迭代器可以將對于一個聚合對象內(nèi)部元素的訪問與業(yè)務(wù)邏輯分離開。
一般分為內(nèi)部迭代器和外部迭代器:
內(nèi)部迭代器只需一次初始調(diào)用,不需要關(guān)心迭代器的內(nèi)部實現(xiàn);
外部迭代器需要顯式地請求下一個元素,因此可以手工控制迭代過程和順序,例如調(diào)用iterator.next();
無論是哪種迭代器,只要聚合對象有l(wèi)ength屬性并且可以通過下標(biāo)訪問,那么就可以被迭代。因此類數(shù)組對象及字面量對象(用for in)都可以。
絕大部分語言都內(nèi)置了迭代器。
應(yīng)用:
可以通過添加終止條件來中斷迭代:在callback函數(shù)中判斷,如果return值為false,則通過break跳出迭代循環(huán)。
由此可以設(shè)計根據(jù)瀏覽器類型創(chuàng)建的返回對象,按優(yōu)先級一個個迭代。
模式5 - 訂閱發(fā)布模式
將許多對象弱耦合起來,當(dāng)一個對象的狀態(tài)發(fā)生變化時,所有訂閱了該變化的對象都會收到通知。
DOM事件是典型的訂閱發(fā)布模式,同時我們還可以自定義事件:
var event = { clients : {}, listen : function (signal,fn){ if(!this.clients[signal]) { this.clients[signal] = []; } this.clients[signal].push(fn); }, trigger: function (arguments){ //not only trigger the event, but also send some data var sig = Array.prototype.shift.call(arguments); fns = this.clients[sig]; if(!fns || fns.length === 0) return false; for(var i = 0; i < fns.length; i++) { var fn = fns[i]; fn.apply(this, arguments); } }, remove: function (signal,fn){ var fns = this.clients[signal]; if(!fns) return false; if(!fn) { //remove all fns delete this.clients[signal]; } else { for(var i = 0; i可以通過離線消息棧來保存沒有被訂閱的但是發(fā)生了的事件,等到有人訂閱再依次取出執(zhí)行。
應(yīng)用:
網(wǎng)站登錄-當(dāng)用戶登錄成功并且ajax返回數(shù)據(jù)后,trigger事件,需要用到用戶數(shù)據(jù)的渲染模塊訂閱該事件。模式6-命令模式
可以解決請求發(fā)送者和請求接受者之間的耦合關(guān)系。實際上,我們只需要調(diào)用command對象中的execute方法就行,他會自動調(diào)用命令接收者對應(yīng)的命令。
示例:
var tv = { open: function() { console.log("open tv"); }, close: function() { console.log("turn off tv"); }, nextChannel: function() { console.log("next channel"); } } //相當(dāng)于我把receiver的一些可用操作封裝到command對象里了,并且提供了統(tǒng)一的接口 var openTVCmd = function(receiver) { return { execute: function(){ receiver.open(); }, undo : function() { //go to previous channel } } } var btn1 = document.getElementById("btn1"); var btn2 = document.getElementById("btn2"); var setCmd = function(button, cmd) { button.onclick = function(){ cmd.execute(); } } var opentvcmd = new openTVCmd(); setCmd(btn1, opentvcmd); btn2.onclick = function(){ //undo command opentvcmd.undo(); }應(yīng)用:
可實現(xiàn)命令的撤銷和重做,只需紀(jì)錄一個oldState或者使用一個緩存來存放歷史命令;
可實現(xiàn)命令隊列,將command對象壓入堆棧,只需依次調(diào)用他們的execute函數(shù),由此可實現(xiàn)宏命令;
可分為智能命令和傻瓜命令:
1.智能命令不需要知道receiver,可自己完成請求,代碼上類似策略模式,但目的不同;
2.傻瓜命令則只負(fù)責(zé)將請求傳遞給真正的receiver。模式7-組合模式
組合模式將對象組合成樹形結(jié)構(gòu),以表示層級結(jié)構(gòu)。借助于對象的多態(tài)性,它使得用戶可以統(tǒng)一地對待組合對象(單個對象的組合)和單個對象。
應(yīng)用:
可實現(xiàn)宏命令,只需要調(diào)用根結(jié)點的execute,程序會自動遍歷整棵樹并依次執(zhí)行各中間節(jié)點和葉結(jié)點的execute函數(shù)。重點是,葉結(jié)點與中間結(jié)點有統(tǒng)一借口。
可用來模擬文件和文件夾層級結(jié)構(gòu):
示例:
var Folder = function(name) { this.name = name; this.files = []; } Folder.prototype.add = function(file) { this.files.push(file); } Folder.prototype.scan = function() { console.log("begin scanning folder "+ this.name); for(var i=0; i注意,層級1與層級2結(jié)點之間并非父子關(guān)系,只是因為他們有統(tǒng)一的借口而被聯(lián)系在一起。
可以對這兩種結(jié)點建立雙向映射,即使文件1里面含有其父結(jié)點的引用,這樣子在刪除一個文件時就需要將其在其父結(jié)點的files中刪除。組合模式使得用戶可以忽略組合對象和單個對象的差異而統(tǒng)一對待,但這也會使得每個對象看上去都差不多,增加代碼理解的難度。
P.s. 本文總結(jié)自《JavaScript設(shè)計模式與開發(fā)實踐》,曾探著
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91264.html
摘要:設(shè)計模式是以面向?qū)ο缶幊虨榛A(chǔ)的,的面向?qū)ο缶幊毯蛡鹘y(tǒng)的的面向?qū)ο缶幊逃行┎顒e,這讓我一開始接觸的時候感到十分痛苦,但是這只能靠自己慢慢積累慢慢思考。想繼續(xù)了解設(shè)計模式必須要先搞懂面向?qū)ο缶幊?,否則只會讓你自己更痛苦。 JavaScript 中的構(gòu)造函數(shù) 學(xué)習(xí)總結(jié)。知識只有分享才有存在的意義。 是時候替換你的 for 循環(huán)大法了~ 《小分享》JavaScript中數(shù)組的那些迭代方法~ ...
摘要:首先,需要來理清一些基礎(chǔ)的計算機編程概念編程哲學(xué)與設(shè)計模式計算機編程理念源自于對現(xiàn)實抽象的哲學(xué)思考,面向?qū)ο缶幊淌瞧湟环N思維方式,與它并駕齊驅(qū)的是另外兩種思路過程式和函數(shù)式編程。 JavaScript 中的原型機制一直以來都被眾多開發(fā)者(包括本人)低估甚至忽視了,這是因為絕大多數(shù)人沒有想要深刻理解這個機制的內(nèi)涵,以及越來越多的開發(fā)者缺乏計算機編程相關(guān)的基礎(chǔ)知識。對于這樣的開發(fā)者來說 J...
摘要:函數(shù)式編程前端掘金引言面向?qū)ο缶幊桃恢币詠矶际侵械闹鲗?dǎo)范式。函數(shù)式編程是一種強調(diào)減少對程序外部狀態(tài)產(chǎn)生改變的方式。 JavaScript 函數(shù)式編程 - 前端 - 掘金引言 面向?qū)ο缶幊桃恢币詠矶际荍avaScript中的主導(dǎo)范式。JavaScript作為一門多范式編程語言,然而,近幾年,函數(shù)式編程越來越多得受到開發(fā)者的青睞。函數(shù)式編程是一種強調(diào)減少對程序外部狀態(tài)產(chǎn)生改變的方式。因此,...
摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點分為新聞熱點開發(fā)教程工程實踐深度閱讀開源項目巔峰人生等欄目。背后的故事本文是對于年之間世界發(fā)生的大事件的詳細(xì)介紹,闡述了從提出到角力到流產(chǎn)的前世今生。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點;分為新聞熱點、開發(fā)教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡迎...
摘要:是文檔的一種表示結(jié)構(gòu)。這些任務(wù)大部分都是基于它。這個實踐的重點是把你在前端練級攻略第部分中學(xué)到的一些東西和結(jié)合起來。一旦你進(jìn)入框架部分,你將更好地理解并使用它們。到目前為止,你一直在使用進(jìn)行操作。它是在前端系統(tǒng)像今天這樣復(fù)雜之前編寫的。 本文是 前端練級攻略 第二部分,第一部分請看下面: 前端練級攻略(第一部分) 在第二部分,我們將重點學(xué)習(xí) JavaScript 作為一種獨立的語言,如...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍(lán)圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
閱讀 383·2023-04-25 16:38
閱讀 1497·2021-09-26 09:46
閱讀 3343·2021-09-08 09:35
閱讀 2793·2019-08-30 12:54
閱讀 3261·2019-08-29 17:06
閱讀 1032·2019-08-29 14:06
閱讀 3356·2019-08-29 13:00
閱讀 3473·2019-08-28 17:53