javascript 設計模式 --單例模式

單例模式定義:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
單例模式場景:有一些對象往往只需要有一個,比如線程池、全局緩存瀏覽器中的Windows對象等
1、實現單例模式
要實現一個標準的單例模式並不複雜,無非是用一個變量來標誌當前是否已經爲某個類創建過對象,如果是則在下一次獲取該類的實例時,直接返回之前創建的對象
image.png
或者:

     var Singleton = function(name) {
        this.name = name;
    }
    Singleton.prototype.getName = function() {
        console.log(this.name)
    }
    Singleton.getInstance = (function(name) {
        var instance = null
        return function(name) {
            if(!instance) {
                instance = new Singleton(name)
            }
            return instance
        }
    })()
    var a = Singleton.getInstance('aa')
    var b = Singleton.getInstance('bb')
    console.log(a === b) // true

但是這種方法增加了類的“不透明性”,Singleton必須知道這是一個單例類,且getInstance方法是不透明的,使用必須知道又該方法,當我們打印console.log(new Singleton('cc')),結果如下:
image.png

2、透明的單例模式
目的:創建該類時候,可以像使用其他普通類一樣;
例子:我們將創建一個CreateDiv單例類,它的作用是在頁面中創建唯一的div節點
image.png
image.png
這裏可以看到當我們console.log(b)時,構造函數html的值還是'marin',到這裏我要明確一點 單例模式定義:保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
但是它還是有一些缺點。未了把判斷的標誌變量instance封裝起來,我們使用了匿名函數(自運行)和閉包,並讓讓這個匿名函數返回真正的Singleton構造方法,這讓閱讀起來很難理解,同時增加了程序的複雜程度
var CreateDiv = function(html) {

if(instance) {
    return instance
}
this.html = html;
this.init();
return instance = this

}
這段代碼中 CreateDiv的構造函數實際負責兩件事,1、創建實例對象(instance=this)並保證只用一個實例if(instance)。2、執行初始化init()。這裏還有個缺點(函數的單一職責原則)
假如我們某一天需要用這個類,在頁面創建多個div,即要讓這個類從單例類變成一個普通的可以生產多個實例的類,那我們就必須改寫CreateDiv構造函數,把控制創建唯一的標誌變量 var instance去掉,這種修改會帶來不必要的煩惱。

3、用代理來實現單例模式
image.png
這樣一來就將 CreateDiv變成一普通類,僅僅去創建div,
實現單例模式讓ProxySingleton 去實現
單例模式的核心是確保只有一個實例,並提供全局訪問

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章