javascript 設(shè)計(jì)模式(文章很長(zhǎng),請(qǐng)自備瓜子,水果和眼藥水)
本文關(guān)鍵詞:JavaScript設(shè)計(jì)模式,由筆耕文化傳播整理發(fā)布。
一直都在考慮這個(gè)月分享大家什么東西最好,原計(jì)劃是打算寫一些HTML5中JS方面的內(nèi)容或者是AJAX方面的,可是自己由于表達(dá)能力,時(shí)間,還有個(gè)人工作方面的問題,這個(gè)還是等下個(gè)月再做分享吧^.^。
老規(guī)矩,開始正文以前先交代自己寫這篇文章的目的和一些注意事項(xiàng):
1.首先本人一直從事前端開發(fā),所以除了JavaScript其他的語言了解不深,所以文章只會(huì)以JavaScript語言的角度去論證;
2.其實(shí)我個(gè)人在項(xiàng)目用過的模式也不多,對(duì)模式的概念的理解也沒有那么抽象,所以最近在面試中如果面試官問到與模式相關(guān)的問題,自己感覺在對(duì)答過程中很郁悶,很多東西表達(dá)不清楚,于是就找了些相關(guān)資料,才會(huì)有這篇文章分享;
3.JavaScript模式與前端的工作和成長(zhǎng)密不可分,因?yàn)檫@確實(shí)不是一個(gè)簡(jiǎn)單的話題,所以我只能盡力用簡(jiǎn)單表達(dá)和例子闡明,而且園子里有很多的高手,所以希望大家踴躍發(fā)言(由于水平有限,請(qǐng)大家多多指教,希望嘴下留情);
4.由于這篇文章更多的只是想起到一個(gè)介紹和講解的作用,并不打算對(duì)每種模式進(jìn)行細(xì)致的分析,所以每種模式只用到一個(gè)至二個(gè)例子,可能會(huì)造成這個(gè)例子的表達(dá)并不是最優(yōu)的或者不夠全面,如果各位看官覺得不過癮,可以再去查找相關(guān)資料;
5.做任何事都需要堅(jiān)持,寫博客也是一樣,嘿嘿,每月至少一篇(文章確實(shí)較長(zhǎng),希望能對(duì)朋友們有所幫助,重點(diǎn)部分在前言中有介紹,大家可以選擇感興趣的模式進(jìn)行深入)。
6.歡迎轉(zhuǎn)載,不過請(qǐng)注明出處,謝謝。
了解JavaScript設(shè)計(jì)模式我們需要知道的一些必要知識(shí)點(diǎn):(內(nèi)容相對(duì)基礎(chǔ),高手請(qǐng)?zhí)^)
閉包:關(guān)于閉包這個(gè)月在園子里有幾篇不錯(cuò)的分享了,在這我也從最實(shí)際的地方出發(fā),說說我的理解。
1.閉包最常用的方式就是返回一個(gè)內(nèi)聯(lián)函數(shù)(何為內(nèi)聯(lián)函數(shù)?就是在函數(shù)內(nèi)部聲明的函數(shù));
2.在JavaScript中有作用域和執(zhí)行環(huán)境的問題,在函數(shù)內(nèi)部的變量在函數(shù)外部是無法訪問的,在函數(shù)內(nèi)部卻可以得到全局變量。由于種種原因,我們有時(shí)候需要得到函數(shù)內(nèi)部的變量,可是用常規(guī)方法是得不到的,這時(shí)我們就可以創(chuàng)建一個(gè)閉包,用來在外部訪問這個(gè)變量。
3.閉包的用途 主要就是上一點(diǎn)提到的讀取函數(shù)內(nèi)部變量,還有一個(gè)作用就是可以使這些變量一直保存在內(nèi)存中。
4.使用閉包要注意,由于變量被保存在內(nèi)存中,所以會(huì)對(duì)內(nèi)存造成消耗,所以不能濫用閉包。解決方法是 在退出函數(shù)之前,將不使用的局部變量全部刪除。
最后還是上一套閉包的代碼吧,這樣更直觀。
封裝:通過將一個(gè)方法或者屬性聲明為私用的,可以讓對(duì)象的實(shí)現(xiàn)細(xì)節(jié)對(duì)其他對(duì)象保密以降低對(duì)象之間的耦合程度,可以保持?jǐn)?shù)據(jù)的完整性并對(duì)其修改方式加以約束,這樣可以是代碼更可靠,更易于調(diào)試。封裝是面向?qū)ο蟮脑O(shè)計(jì)的基石。
盡管JavaScript是一門面向?qū)ο蟮恼Z言,可它并不具備將成員聲明為公用或私用的任何內(nèi)部機(jī)制,所以我們只能自己想辦法實(shí)現(xiàn)這種特性。下面還是通過一套完整的代碼去分析,介紹什么是私有屬性和方法,什么是特權(quán)屬性和方法,什么是公有屬性和方法,什么是公有靜態(tài)屬性和方法。
私有屬性和方法:函數(shù)有作用域,在函數(shù)內(nèi)用var 關(guān)鍵字聲明的變量在外部無法訪問,私有屬性和方法本質(zhì)就是你希望在對(duì)象外部無法訪問的變量。
特權(quán)屬性和方法:創(chuàng)建屬性和方法時(shí)使用的this關(guān)鍵字,因?yàn)檫@些方法定義在構(gòu)造器的作用域中,所以它們可以訪問到私有屬性和方法;只有那些需要直接訪問私有成員的方法才應(yīng)該被設(shè)計(jì)為特權(quán)方法。
共有屬性和方法:直接鏈在prototype上的屬性和方法,不可以訪問構(gòu)造器內(nèi)的私有成員,可以訪問特權(quán)成員,子類會(huì)繼承所有的共有方法。
共有靜態(tài)屬性和方法:最好的理解方式就是把它想象成一個(gè)命名空間,實(shí)際上相當(dāng)于把構(gòu)造器作為命名空間來使用。
}
JavaScript中這個(gè)很重要的話題。
alert(_m.getName());
代碼都不難,只要對(duì) 原型鏈 有基礎(chǔ)就能理解。類式繼承模式是JavaScript繼承主要的模式,幾乎所有用面向?qū)ο蠓绞骄帉懙腏avaScript代碼中都用到了這種繼承,又因?yàn)樵诟鞣N流行語言中只有JavaScript使用原型式繼承,,因此最好還是使用類式繼承。可是要熟悉JavaScript語言,原型繼承也是我們必須所了解的,至于在項(xiàng)目中是否使用就得看個(gè)人編碼風(fēng)格了。
------------------------------------------ 正文開始了,我是分割線 ------------------------------------------
前言:
JavaScript設(shè)計(jì)模式的作用 - 提高代碼的重用性,可讀性,使代碼更容易的維護(hù)和擴(kuò)展。
1.單體模式,工廠模式,橋梁模式個(gè)人認(rèn)為這個(gè)一個(gè)優(yōu)秀前端必須掌握的模式,對(duì)抽象編程和接口編程都非常有好處。
2.裝飾者模式和組合模式有很多相似的地方,它們都與所包裝的對(duì)象實(shí)現(xiàn)同樣的接口并且會(huì)把任何方法的調(diào)用傳遞給這些對(duì)象。裝飾者模式和組合模式是本人描述的較吃力的兩個(gè)模式,我個(gè)人其實(shí)也沒用過,所以查了很多相關(guān)資料和文檔,請(qǐng)大家海涵。
3.門面模式是個(gè)非常有意思的模式,幾乎所有的JavaScript庫都會(huì)用到這個(gè)模式,假如你有逆向思維或者逆向編程的經(jīng)驗(yàn),你會(huì)更容易理解這個(gè)模式(聽起來有挑戰(zhàn),其實(shí)一接觸你就知道這是個(gè)很簡(jiǎn)單的模式);還有配置器模式得和門面模式一塊拿來說,這個(gè)模式對(duì)現(xiàn)有接口進(jìn)行包裝,合理運(yùn)用可以很多程度上提高開發(fā)效率。這兩個(gè)模式有相似的地方,所以一塊理解的話相信都會(huì)很快上手的。
4.享元模式是一種以優(yōu)化為目的的模式。
5.代理模式主要用于控制對(duì)象的訪問,包括推遲對(duì)其創(chuàng)建需要耗用大量計(jì)算資源的類得實(shí)例化。
6.觀察者模式用于對(duì)對(duì)象的狀態(tài)進(jìn)行觀察,并且當(dāng)它發(fā)生變化時(shí)能得到通知的方法。用于讓對(duì)象對(duì)事件進(jìn)行監(jiān)聽以便對(duì)其作出響應(yīng)。觀察者模式也被稱為“訂閱者模式”。
7.命令模式是對(duì)方法調(diào)用進(jìn)行封裝的方式,用命名模式可以對(duì)方法調(diào)用進(jìn)行參數(shù)化和傳遞,然后在需要的時(shí)候再加以執(zhí)行。
8.職責(zé)鏈模式用來消除請(qǐng)求的發(fā)送者和接收者之間的耦合。
JavaScript設(shè)計(jì)模式都有哪些?
單體(Singleton)模式: 絕對(duì)是JavaScript中最基本最有用的模式。
單體在JavaScript的有多種用途,它用來劃分命名空間?梢詼p少網(wǎng)頁中全局變量的數(shù)量(在網(wǎng)頁中使用全局變量有風(fēng)險(xiǎn));可以在多人開發(fā)時(shí)避免代碼的沖突(使用合理的命名空間)等等。
在中小型項(xiàng)目或者功能中,單體可以用作命名空間把自己的代碼組織在一個(gè)全局變量名下;在稍大或者復(fù)雜的功能中,單體可以用來把相關(guān)代碼組織在一起以便日后好維護(hù)。
使用單體的方法就是用一個(gè)命名空間包含自己的所有代碼的全局對(duì)象,示例:
}
或者
...
8 }
工廠(Factory)模式:提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無需指定他們具體的類。
工廠就是把成員對(duì)象的創(chuàng)建工作轉(zhuǎn)交給一個(gè)外部對(duì)象,好處在于消除對(duì)象之間的耦合(何為耦合?就是相互影響)。通過使用工廠方法而不是new關(guān)鍵字及具體類,可以把所有實(shí)例化的代碼都集中在一個(gè)位置,有助于創(chuàng)建模塊化的代碼,這才是工廠模式的目的和優(yōu)勢(shì)。
舉個(gè)例子:你有一個(gè)大的功能要做,其中有一部分是要考慮擴(kuò)展性的,那么這部分代碼就可以考慮抽象出來,當(dāng)做一個(gè)全新的對(duì)象做處理。好處就是將來擴(kuò)展的時(shí)候容易維護(hù) - 只需要操作這個(gè)對(duì)象內(nèi)部方法和屬性,達(dá)到了動(dòng)態(tài)實(shí)現(xiàn)的目的。非常有名的一個(gè)示例 - XHR工廠:
...
16 }
工廠模式又區(qū)分簡(jiǎn)單工廠模式和抽象工廠模式,上面介紹的是簡(jiǎn)單工廠模式,這種模式用的更多也更簡(jiǎn)單易用。抽象工廠模式的使用方法就是 - 先設(shè)計(jì)一個(gè)抽象類,這個(gè)類不能被實(shí)例化,只能用來派生子類,最后通過對(duì)子類的擴(kuò)展實(shí)現(xiàn)工廠方法。 示例:
}
橋接(bridge)模式:在實(shí)現(xiàn)API的時(shí)候,橋梁模式灰常有用。在所有模式中,這種模式最容易立即付諸實(shí)施。
橋梁模式可以用來弱化它與使用它的類和對(duì)象之間的耦合,就是將抽象與其實(shí)現(xiàn)隔離開來,以便二者獨(dú)立變化;這種模式對(duì)于JavaScript中常見的時(shí)間驅(qū)動(dòng)的編程有很大益處,橋梁模式最常見和實(shí)際的應(yīng)用場(chǎng)合之一是時(shí)間監(jiān)聽器回調(diào)函數(shù)。先分析一個(gè)不好的示例:
};
為什么說這個(gè)示例不好,因?yàn)閺倪@段代碼中無法看出那個(gè)LogFunc方法要顯示在什么地方,它有什么可配置的選項(xiàng)以及應(yīng)該怎么去修改它。換一種說法就是,橋梁模式的要訣就是讓接口“可橋梁”,實(shí)際上也就是可配置。把頁面中一個(gè)個(gè)功能都想象成模塊,接口可以使得模塊之間的耦合降低。
掌握橋梁模式的正確使用收益的不只是你,還有那些負(fù)責(zé)維護(hù)你代碼的人。把抽象于其實(shí)現(xiàn)隔離開,可獨(dú)立地管理軟件的各個(gè)部分,bug也因此更容易查找。
橋梁模式目的就是讓API更加健壯,提高組件的模塊化程度,促成更簡(jiǎn)潔的實(shí)現(xiàn),并提高抽象的靈活性。一個(gè)好的示例:
}
注:橋梁模式還可以用于連接公開的API代碼和私有的實(shí)現(xiàn)代碼,還可以把多個(gè)類連接在一起。在文章封裝介紹的部分提到過特權(quán)方法,也是橋梁模式的一種特例!禞S設(shè)計(jì)模式》上找的示例,加深大家對(duì)這個(gè)模式的理解:
}
裝飾者(Decorator)模式:這個(gè)模式就是為對(duì)象增加功能(或方法)。
動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就擴(kuò)展功能而言,它比生成子類方式更為靈活。
裝飾者模式和組合模式有很多共同點(diǎn),它們都與所包裝的對(duì)象實(shí)現(xiàn)統(tǒng)一的接口并且會(huì)把任何方法條用傳遞給這些對(duì)象?墒墙M合模式用于把眾多子對(duì)象組織為一個(gè)整體,而裝飾者模式用于在不修改現(xiàn)有對(duì)象或從派生子類的前提下為其添加方法。
裝飾者的運(yùn)作過程是透明的,這就是說你可以用它包裝其他對(duì)象,然后繼續(xù)按之前使用那么對(duì)象的方法來使用,從下面的例子中就可以看出。還是從代碼中理解吧:
alert(theString.show()); //output ' 本文關(guān)鍵詞:JavaScript設(shè)計(jì)模式,由筆耕文化傳播整理發(fā)布。
本文編號(hào):208946
本文鏈接:http://www.sikaile.net/wenshubaike/mishujinen/208946.html