# 什么是設計模式
一個模式就是一個可重用的方案,可應用于在軟件設計中的常見問題 - 在我們的例子里 - 就是編寫JavaScript的web應用程序。模式的另一種解釋就是一個我們如何解決問題的模板 - 那些可以在許多不同的情況里使用的模板。 那么理解和熟悉模式為什么是如此的重要?設計模式有以下三點好處:
* 模式是行之有效的解決方法:他們提供固定的解決方法來解決在軟件開發中出現的問題,這些都是久經考驗的反應了開發者的經驗和見解的使用模式來定義的技術。
* 模式可以很容易地重用:一個模式通常反映了一個可以適應自己需要的開箱即用的解決方案。這個特性讓它們很健壯。
* 模式善于表達:當我們看到一個提供某種解決方案的模式時,一般有一組結構和詞匯可以非常優雅地幫助表達相當大的解決方案。
模式不是一個確切的解決方案。我們要記住模式的角色僅僅是給我們提供一個解決方案。模式不能解決所有的設計問題,也不能代替優秀的軟件設計師。然而,它們在幫助我們。接下來我們將看看模式必須提供的其他的一些優勢。
* 模式的重用可以幫助防止在應用程序開發過程中出現的一些可能導致重大問題的小問題。這意味著當代碼是建立在行之有效的模式上時,我們可以花更少的時間去關心我們的代碼結構,從而能花更多的時間關注我們的解決方案的整體質量。這是因為模式可以鼓勵我們在更好的結構化和有組織的方式下編碼,這將避免在未來由于清潔的目的而去重構它。
* 模式可以提供一個不需要綁定到一個特定問題的書面的概括性的解決方案。這個廣義的方法意味著不用管我們正在處理的應用程序 (許多情況下的編程語言) 設計模式的應用可以提高我們的代碼的結構。
* 某些模式可以通過避免重復來減小我們代碼的文件大小。通過鼓勵開發者更仔細地看待他們的解決方案來減少重復的地方,如通過將類似的執行流程作為一個一般性的函數來減少函數的數量,這樣我們就可以減小代碼庫的總體大小,這也成為使代碼更DRY。
* 模式增加了開發者的詞匯,這使得交流更快速。
* 經常使用的模式可通過收集其他使用這些模式的開發人員貢獻給設計模式社區的經驗來改進。在某些情況下,這將導致全新模式的創建,同時也可以提供改進的指導大家如何使用特定的模式才是最好的。這可以確保基于模式的解決方案繼續變得比特別的解決方案更健壯。
## 我們已經每天都在使用模式
為了了解模式有多有用,讓我們看看jQuery提供給我們的一個很簡單的元素選擇問題。 假設我們有一個為頁面上每一個class為"foo"的DOM元素添加一個計數器的腳本,什么才是查詢這個元素的集合的最有效的方法呢?有幾種不同的方法可以解決這個問題:
選擇頁面上所有的元素并存儲它們的引用,然后使用正則表達式 (或其他方式) 來過濾這個集合中那些class為"foo"的元素的引用。
* 使用像asquerySelectorAll()的現代原生瀏覽器的特性,來選擇所有的class為"foo"的元素。
* 使用像asgetElementsByClassName()的原生特性同樣可以獲取期望的集合。
那些,這些選擇哪個是最快的呢?實際上第三個,比其他的替代選擇快 8-10倍。但在實際的應用程序中,第三個選擇無法在Internet Explorer 9以下的版本中使用,從而只能使用第一個,第二個和第三個都不支持。
使用jQuery的開發人員就不必擔心這個問題,因為很幸運的是它使用Facade模式把這個問題抽象了出來。正如我們即將在后面更詳細的介紹的那樣,這種模式提供了一組簡單的對更復雜的底層代碼的抽象接口 (例如$el.css(),$el.animate()) 。正如我們所看到的,這意味著我們只會對實現級別的細節花費更少的時間。
在其后,庫會根據我們當前瀏覽器的支持自動選擇最優的方法來選擇元素,我們只使用抽象層。
我們可能都熟悉jQuery的$("selector"),這是更容易使用的在一個頁面選擇HTML元素的方法,這樣我們就不必手動來選擇getElementById(),getElementsByClassName(),getElementByTagName()等方法。
雖然我們知道querySelectorAll()試圖解決這個問題,但比比使用jQuery的Facade接口和自己來選擇最優的方式時花費的精力,毫無疑問,使用模式可以提供真實世界的抽象價值。
我們將在本書的后面看到更多的設計模式。
## “模式特性”測試,模式原型和三條規則
記住并不是每個算法、每個最佳實踐和每個解決方案都可能被認為是一個完整的模式。這兒可能缺少了幾個關鍵因素,而且模式社團除非經過嚴格的審查才謹慎地聲明某東西為模式的。即使某東西對我們來說似乎滿足了模式標準,它都不應該被當作模式,直到它由他人經過適當時間的周密調查和測試后才可能當作模式。
回頭看看Alexander曾經做過的工作,他聲明模式應當既是過程也是“事物”。這個定義故意不明確,因為他緊跟著說模式應該是創建“事物”的過程。這就是為什么模式通常集中定位在表面上可識別的結構的原因。例如,我們應當能夠可視化地描繪(或者繪制)圖片來展示把模式應用到實踐中的結構。
在研究設計模式的時候,無意間碰到術語“模式原型”是很正常的。那么什么是模式原型呢? 好,仍然沒有通過"模式特性”測試的模式通常認為是模式原型。模式原型也許源自于某人已經確定的值得與社團共享的特定解決方案的工作,然而由于它提出時間短,所以可能仍然沒有機會接受嚴格的審查。
另外,個人共享的模式也許沒有時間或者沒有興趣通過“模式特性”測試這個過程,不過可能發布了這些模式原型的簡短說明。這種類型模式的簡要描述或者片段就是眾所周知的小模式。
全面文檔化具有資格的模式這樣的工作是非常令人氣餒的。回頭看看設計模式領域最早期的某些工作,如果一個模式能做到以下事情,那么這個模式就可以認為是“好的”模式:
* 解決一類特定的問題:模式不能假設僅僅關注原理或者策略。它們需要關注解決方案。這是好的模式最重要的因素之一。
* 問題的解決方案不是表面上的:我們發現解決問題的技術常常首先試圖源自于某個眾所周知的原理。最佳的設計模式通常間接地提供問題的解決方案-認為模式是與設計相關的最具有挑戰性的問題必然的解決方法。
* 所描述的想法一定得到了證明:設計模式需要提供所描述的它們運行的證據,如果沒有這些證據,就不會認真的考慮這個設計。如果模式事實上是高度理論性的話,那么只有冒險者才可能試著用它。
* 它必須說明與代碼之間關系:在某些情況下,模式似乎說明了一種類型的模塊。雖然實現的可能就是這個方法,但是官方的模式說明一定要更深入的描述系統結構和機制,以解釋它與代碼之間的關系。
我們認為不滿足準則的模式原型不值得學習,這可以得到諒解,然而,事實遠不是這樣的。許多模式原型確實非常的好。我不是說所有的模式原型都值得看,不過總有幾個在自然環境下成長的有用的模式原型可以在未來的項目中幫到我們。從心底里使用上面列表來做最佳評判的話,你在選擇哪個是模式的過程中將感覺非常愉快。
模式是否有效的附加要求之一是模式要展示某些重現現象。這個就是至少在三個關鍵方面 ,也就是三條規則驗證是否取得資格經常要做的事情。為了展示使用這個規則后的重現,模式必須證明其:
* 適用性-模式怎樣才能被認為是成功的。
* 有用性-為什么認為這個模式是成功的?
* 可用性?-因為設計得到廣泛的應用,所以認為這個設計就是模式嗎?如果是這樣的話,那么需要說明。重新審核或者定義模式的時候,牢記以上規則非常重要。
- 前言
- 簡介
- 什么是設計模式?
- 設計模式的結構
- 編寫設計模式
- 反模式
- 設計模式的分類
- 設計模式分類概覽表
- JavaScript 設計模式
- 構造器模式
- 模塊化模式
- 暴露模塊模式
- 單例模式
- 觀察者模式
- 中介者模式
- 原型模式
- 命令模式
- 外觀模式
- 工廠模式
- Mixin 模式
- 裝飾模式
- 亨元(Flyweight)模式
- JavaScript MV* 模式
- MVC 模式
- MVP 模式
- MVVM 模式
- 最新的模塊化 JavaScript 設計模式
- AMD
- CommonJS
- ES Harmony
- JQuery 中的設計模式
- 組合模式
- 適配器模式
- 外觀模式
- 觀察者模式
- 迭代器模式
- 惰性初始模式
- 代理模式
- 建造者模式
- jQuery 插件的設計模式
- JavaScript 命名空間模式
- 總結
- 參考