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