摘要:在面向?qū)ο蟮恼Z言中,比如,等,單例模式通常是定義類時(shí)將構(gòu)造函數(shù)設(shè)為,保證對象不能在外部被出來,同時(shí)給類定義一個(gè)靜態(tài)的方法,用來獲取或者創(chuàng)建這個(gè)唯一的實(shí)例。
萬事開頭難,作為正經(jīng)歷菜鳥賽季的前端player,已經(jīng)忘記第一次告訴自己要寫一些東西出來是多久以的事情了。。。如果,你也和我一樣,那就像我一樣,從現(xiàn)在開始,從看到這篇文章開始,打開電腦,敲下你的第一篇文章(或者任何形式的文字)吧。
首先,respect一下:以下文章內(nèi)容全部來自最近在看的一本書《javascript設(shè)計(jì)模式與開發(fā)實(shí)踐》,作者曾探。感謝作者的辛苦付出,以下內(nèi)容算是個(gè)人的一個(gè)讀書筆記,如果有理解有誤或不合適的內(nèi)容,歡迎隨時(shí)聯(lián)系更改或刪除。
其次,歡迎各路大神diss。
最后,接下來正式開始我的flow。
一、什么是設(shè)計(jì)模式
相信任何一個(gè)從事和代碼相關(guān)工作的人都或多或少地聽說過“設(shè)計(jì)模式”這個(gè)名詞,每個(gè)人也都有自己的理解。從我個(gè)人來看,設(shè)計(jì)模式就是“套路”,知道了這個(gè)套路的話,你就多了一些處理問題的技能(或者是更優(yōu)雅地解決);那么,如果不知道這個(gè)套路也并不能說明什么,只是你還沒總結(jié)或者你正在使用卻不自知而已。即使是真的不知道,也沒關(guān)系,就從這篇文章開始吧。
設(shè)計(jì)模式的思想來源于建筑行業(yè),建筑學(xué)的研究人員花了長達(dá)20年的時(shí)間總結(jié)了在建筑中為解決同樣的問題而設(shè)計(jì)的不同的建筑結(jié)構(gòu),從中找到一些高質(zhì)量的相似的通用結(jié)構(gòu),稱之為“模式”,軟件工程大神們受到啟發(fā),進(jìn)而總結(jié)了23種常用的軟件開發(fā)設(shè)計(jì)模式,錄入到《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》
設(shè)計(jì)模式的定義是:在面向?qū)ο筌浖O(shè)計(jì)過程中針對特定問題的簡潔而優(yōu)雅的解決方案(并不必須是面向?qū)ο螅?。通俗來說,設(shè)計(jì)模式就是給我們軟件開發(fā)過程中經(jīng)常用的一些套路起了一個(gè)名字,就變成了一個(gè)看起來很高大上的東西。
建筑會(huì)因?yàn)椴煌娘L(fēng)格去對一些相同的結(jié)構(gòu)做一些不一樣的設(shè)計(jì),對軟件來說也一樣,不同的語言,設(shè)計(jì)模式的實(shí)現(xiàn)也是不一樣的。google的某一位大神曾經(jīng)在文章中指出23種設(shè)計(jì)模式有16種已經(jīng)在lisp中默認(rèn)實(shí)現(xiàn)了。比如,命令模式,在java中需要一個(gè)命令類,一個(gè)接受者類,一個(gè)調(diào)用者類,并把命令對象在接受者類中四處傳遞。但在lisp或javascript這種將函數(shù)作為一等公民的語言中,函數(shù)本身就可以在對象中互相傳遞,因此,命令模式在這兩種語言中就成為了一種隱性模式。
智者說,凡是都有度(別問我是哪個(gè)智者)。對于鼓吹設(shè)計(jì)模式和貶低設(shè)計(jì)模式的,我只能說,你牛你有理。個(gè)人認(rèn)為應(yīng)該沒有放之四海而皆準(zhǔn)的東西(貌似是個(gè)悖論,尷尬)。如果有,那就有吧,反正不是設(shè)計(jì)模式。為什么說設(shè)計(jì)模式簡潔而優(yōu)雅的解決方案,是因?yàn)閺能浖_發(fā)的角度來看,健壯和易擴(kuò)展是非常非常重要的衡量指標(biāo),而設(shè)計(jì)模式恰恰幫助我們更好地解決了這個(gè)問題。但為什么說“度”呢,因?yàn)樵O(shè)計(jì)模式也并不適合用在任何開發(fā)的過程中。如果在一個(gè)簡單的小項(xiàng)目中,明明一個(gè)函數(shù)就可以完成的功能,非要為了炫技或其他什么原因,增加額外的許多代碼實(shí)現(xiàn)一個(gè)模式,項(xiàng)目代碼增加許多,自然增加了bug的幾率。另外,明明是一次使用的東西,偏偏要做過度的設(shè)計(jì)去用模式做擴(kuò)展設(shè)計(jì),這自然也是沒有必要的。
二、設(shè)計(jì)模式之單例模式
單例模式應(yīng)該是設(shè)計(jì)模式中最簡單的一個(gè)模式,在許多書中都是作為第一個(gè)來講。單例,顧名思義,保證一個(gè)類只有一個(gè)實(shí)例,并在項(xiàng)目代碼中可以全局被訪問。
在面向?qū)ο蟮恼Z言中,比如,c++、java等,單例模式通常是定義類時(shí)將構(gòu)造函數(shù)設(shè)為private,保證對象不能在外部被new出來,同時(shí)給類定義一個(gè)靜態(tài)的方法,用來獲取或者創(chuàng)建這個(gè)唯一的實(shí)例。javascript同樣可以模仿這個(gè)過程來實(shí)現(xiàn)單例,代碼如下:
var Singleton = function (name) { this.name = name; this.instance = null; } Singleton.getInstance = function(name) { if (!this.instance) { this.instance = new Singleton(name); } return this.instance; }
很顯然,我們在代碼中需要用到Singleton的時(shí)候,只需要Singleton.getInstance("PGOne")即可獲得唯一的實(shí)例。但是卻有一些缺陷:當(dāng)我們new Singleton("Gai")的時(shí)候,仍可以new出實(shí)例,另外,Singleton做了一些和自己無關(guān)的事情,于是乎就有了另一種實(shí)現(xiàn)。
var Singleton = function (name) { this.name = name; this.instance = null; } var ProxySingleton = (function () { var instance; return function (name) { if (!instance) { instance = new Singleton(name); } return instance; } })();
在這種實(shí)現(xiàn)中,我們可以通過new ProxySingleton("PGOne")獲取Singleton的實(shí)例,單例控制就分離到了代理類中,保證了Singleton的純潔。甚至可以把Singleton使用閉包封裝成私有變量,徹底阻止直接的new調(diào)用。
上面這些是在JavaScript中模仿靜態(tài)語言c++或java中單例模式的實(shí)現(xiàn),但是,在JavaScript中,看起來似乎有些奇怪和多余。因?yàn)?,JavaScript作為一種無類(class-freee)語言,生搬過來的單例模式并沒有太多意義。在JavaScript中,常見對象非常簡單,如果需要一個(gè)單例,我們只需要聲明一個(gè)字面量的對象,作為全局變量就可以了,何必聲明一個(gè)構(gòu)造函數(shù),再去new出來呢?雖然全局變量不是單例模式,但是在JavaScript中,我們卻常常把全局變量當(dāng)做單例模式來用,因?yàn)樗_實(shí)能完成單例模式的功能。但是全局變量最大的問題就是污染全局空間,以至于一直以來,濫用全局變量都被視為糟糕的代碼。為了盡可能減少全局變量的影響,在JavaScript中,命名空間和閉包封裝私有變量成了慣用的手段。那么在JavaScript中,單例到底應(yīng)該是什么樣子呢?JavaScript終極單例如下:
var Singleton = function (fn) { var result; return function () { return result || (result = fn.apply(this, arguments)); } } var createSingleDialog = function() { var div = document.createElement("div"); div.innerHTML = "我是彈窗"; div.style.display = "none"; document.body.appendChild("div"); return div; } // 使用 var getDialog = Singleton(createSingleDialog); document.getElementById("btn").onclick = function () { var dialog = getDialog(); dialog.style.display = "block"; }
在上面代碼中,Singleton是一個(gè)通用的代理管理器,可以通過傳入不同的功能函數(shù)進(jìn)而返回一個(gè)單例獲取器。在上面代碼中,是獲取一個(gè)彈窗的單例,我們同樣可以通過傳入一個(gè)導(dǎo)航欄生成函數(shù),來獲取一個(gè)導(dǎo)航欄的單例。另外,上面代碼中,單例只在需要的時(shí)候才會(huì)被創(chuàng)建,這也是單例模式所要求的,然而,通過全局對象和閉包實(shí)現(xiàn)的單例,確實(shí)在開始就創(chuàng)建了實(shí)例。
需要說明的是,由于javascript的應(yīng)用場景主要在瀏覽器,通過dom操作也同樣可以做到單例,所以new這樣的單例看起來使用場景并不大,但是,上面的一小段代碼遠(yuǎn)不止單例那么簡答。在實(shí)際的開發(fā)中,我們經(jīng)常會(huì)遇到這樣的問題,在異步獲取數(shù)據(jù)之后或是彈窗出來的時(shí)候,需要給一部分的dom元素綁定事件。比如說,有一個(gè)負(fù)責(zé)數(shù)據(jù)展示和操作的彈窗,每次彈窗顯示的時(shí)候都需要將新的數(shù)據(jù)綁定到彈窗的dom元素上,這時(shí)就會(huì)遇到dom重復(fù)綁定事件的問題,上面代碼就可以完美解決這個(gè)問題。
var bindEvent = getSingle(function () { document.getElement("btn").onClick = function(){ alert("new data"); } return true; }); var showDialog = function () { console.log("顯示彈窗"); bindEvent(); } showDialog(); showDialog();
第一次寫東西,感覺想要把一個(gè)東西寫清楚還真是一件復(fù)雜的事情。
許久不見朋友突然的一個(gè)約飯,幫朋友搬一天的家,諸多借口,又差點(diǎn)掐死了這篇內(nèi)容。還好,我今天不困。復(fù)制粘貼一番,勉強(qiáng)寫出來一點(diǎn)。
設(shè)計(jì)模式,未完待續(xù)。。。。
番外:
to be real很酷,但請不要為了real而real。人人都向往自由,但世界卻不能沒了規(guī)則??吞祝埐灰傺b不懂。
----中國有嘻哈觀感,我站萬磁王!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/85224.html
摘要:但是,不合理地濫用閉包,也會(huì)造成很多性能問題,從而使項(xiàng)目維護(hù)成本增加。 前言 相信很多小伙伴在工作或者面試過程中都遇到過這個(gè)問題,作為經(jīng)典的前端面試題之一,它高頻地出現(xiàn)在我們的求職生涯中。所以,了解和掌握它也就變得十分必要了 讀完這篇文章,你或許就會(huì)知道: 閉包是什么,它是怎么形成的 為什么要使用閉包 閉包會(huì)造成哪些問題 如果文章中有出現(xiàn)紕漏、錯(cuò)誤之處,還請看到的小伙伴多多指教,先...
摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個(gè)最重要的技術(shù)點(diǎn)常用整理網(wǎng)頁性能管理詳解離線緩存簡介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實(shí)現(xiàn)的大排序算法一怪對象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個(gè)最重要的技術(shù)點(diǎn) 常用meta整理 網(wǎng)頁性能管理詳解 HTML5 ...
摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個(gè)最重要的技術(shù)點(diǎn)常用整理網(wǎng)頁性能管理詳解離線緩存簡介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實(shí)現(xiàn)的大排序算法一怪對象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個(gè)最重要的技術(shù)點(diǎn) 常用meta整理 網(wǎng)頁性能管理詳解 HTML5 ...
摘要:對深度學(xué)習(xí)模型而言,水就是海量的數(shù)據(jù)。就拿機(jī)器識(shí)別物體這樣的任務(wù)來說,通過數(shù)百萬副圖片的訓(xùn)練,深度學(xué)習(xí)模型甚至可以超過人的肉眼的識(shí)別能力,這確實(shí)是人工智能在感知類問題上重要的里程碑。關(guān)于深度學(xué)習(xí),還有一個(gè)有趣的現(xiàn)象。 說到人工智能和機(jī)器人,上點(diǎn)兒歲數(shù)的碼農(nóng)們可能對封面這張圖有點(diǎn)印象。不明就里的朋友,可以回去補(bǔ)習(xí)一下《編輯部的故事》。我是個(gè)二手的人工智能表演藝術(shù)家:從博士畢業(yè)開始,就在MSRA...
閱讀 2269·2021-11-15 11:38
閱讀 1218·2021-09-06 15:02
閱讀 3475·2021-08-27 13:12
閱讀 1462·2019-08-30 14:20
閱讀 2460·2019-08-29 15:08
閱讀 710·2019-08-29 14:08
閱讀 1776·2019-08-29 13:43
閱讀 1572·2019-08-26 12:11