設計模式是:在軟件設計過程當中針對「特定」問題的「簡潔而優雅」的解決方案。javascript
在軟件開發的歷史中,沉澱了一些好的軟件設計,而設計模式即是給這些好設計取了個名字。「好的設計」並非某人發明的。一個稍有經驗的程序員也許在不知不覺中數次使用過這些設計模式。前端
設計模式的意義是讓人們寫出可複用和可維護性高的程序。java
舉個例子,假設有一個空房間,咱們要日復一日地往裏面放一些東西。最簡單的辦法固然是把這些東西直接扔進去,可是時間久了,就會發現很難從這個房子裏找到本身想要的東西,要調整某幾樣東西的位置也不容易。程序員
因此在房間裏作一些櫃子也許是個更好的選擇,雖然櫃子會增長咱們的成本,但它能夠在維護階段爲咱們帶來好處。使用這些櫃子存放東西的規則,或許就是一種模式。設計模式
全部設計模式的實現都遵循一條原則,即「找出程序中變化的地方,並將變化封裝起來」。瀏覽器
一個程序的設計老是能夠分爲可變的部分和不變的部分。當咱們找出可變的部分,而且把這些部分封裝起來,那麼剩下的就是不變和穩定的部分。這些不變和穩定的部分是很是容易複用的。緩存
熟悉這些模式的程序員,對某些模式的理解也造成了條件反射,當合適的場景出現時,他們能夠很快地找到某種模式做爲解決方案。閉包
咱們主要學習如下模式:app
單例模式的定義是:「保證僅有一個實例,並提供一個訪問它的全局訪問點」。dom
單例模式是一種經常使用的模式,有一些對象咱們每每只須要一個,好比全局緩存、瀏覽器中的 window 對象等。
舉個前端的例子,網頁loading圖(菊花圖)。頁面整個生命週期,咱們只須要生成一個loading就行了。既簡化了邏輯(沒必要去考慮多個請求打開了多個loading)又減小了dom的建立。
在javascript
中,函數是一等公民,因此例子我都優先使用函數來實現(原書是以面向對象的形式展示)
function generateInstance() { return { say() { console.log('hello') } } } let single = (function() { let instance // 哨兵變量 return function getSingle() { if (!instance) { // 若是尚未生成實例,那麼生成一個。 instance = generateInstance() } return instance } })() let a = single() let b = single() console.log(a === b) // true
以上就是一個單例的例子了。
咱們利用閉包保存了一個哨兵變量,用來判斷單例是否生成。
下面是一個生成單例的高階函數。
var getSingle = function(fn) { var result return function() { return result || (result = fn.apply(this, arguments)) } } // 用法 let singeName = getSingle(() => `hello ${Math.random()}`) let a = singeName() let b = singeName() console.log(a === b) // true