[JavaScript設計模式] 什么是單例模式


概念

保證一個類僅有一個實例,並提供一個全局訪問點

為什么要用單例模式

想象一下某些web應用,當點擊登錄按鈕時,會彈出一個登錄框,無論你點擊多少次這個登錄按鈕,登錄框都只會出現一個,不會出現多個登錄框。同時不會頻繁的進行刪除和添加,而是同一個登錄框進行隱藏和顯示,因為刪除和添加十分耗費性能,所以單例可以達到最大化的效能利用。登錄框這個例子就是單例模式最典型的應用,符合業務的需求,又能夠提高性能

單例模式的實現

簡單的單例模式

一個簡單的單例模式,無非就是用一個變量指示要創建的實例是否已經創建過了,如果已經創建過了,則在下一次使用實例時,直接返回復用,如果沒有創建過,則創建並保存到變量中。

但是這時候的這個單例類是“不透明”的,因為我們通常習慣使用new XXX()的方式來實例化一個類,而不是通過使用者不知道的XXX.getInstance()的方式來獲取單例對象。
所以我們應該使用透明的單例類

透明的單例類

先介紹下IIFE

IIFE( 立即調用函數表達式)是一個在定義時就會立即執行的 JavaScript 函數 --- MDN

eg.

之所以使用IIFE,就是限制JS的變量作用域,在ES5中,沒有塊級作用域,只有函數作用域一種,所以提供一種模擬塊級作用域的方法就是IIFE。我們的透明單例模式就是使用IIFE來模擬。

使用IIFE來避免變量污染,把在IIFE中創建的類return出去,供外部通過new XXX()的形式調用。缺點是增加了程序的復雜度,不利於閱讀。
在構造函數CreateDiv中:

實際上做了兩件事,

  1. 保證類只有一個實例
  2. 構造實例

這樣就不符合單一職責原則,這個構造函數就變得不純粹了。如果哪天我不想使用單例了,我要在頁面創建普通的實例,創建多個不一樣的div,還需要去修改CreateDiv構造函數,去掉控制單一實例的那一段,但頁面中使用此單例的代碼可能就用不了,故會帶來不必要的麻煩。所以我們應該使用單例代理。

使用代理的單例類

上面的問題我們可以用單例代理來解決,通過引入一個代理類,代理普通CreateDiv類,使之變為單例類。

我們把負責單例類管理的邏輯放到了單獨的ProxyCreateDiv類中,CreateDiv類還是一個普通的創建實例的類,這樣保證了單一職責原則,組合起來就能達到單一職責原則。

以上就是單例類的創建模式,還有一類單例模式的應用,就是文章開頭說的登錄框,點擊登錄按鈕,登錄框會彈出,而無論點擊多少次,登錄框都只會彈出一個,這個登錄框就是單例的,稍后我會新寫一篇文章分享這種單例模式的應用,敬請關注。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM