設計模式之單例模式(《JavaScript設計模式與開發實踐》讀書筆記)

newAir發表於2018-06-07

單例模式,傳說中最簡單,最容易理解的設計模式

其實單例模式有很多方式去實現,下面我將書上所說一一展現

最簡單的實現方式

    var Singleton = function (name) {
        this.name = name;
        this.instance = null; //暫存例項
    }
    
    Singleton.prototype.getName = function () {
        alert(this.name)
    }
    
    Singleton.getInstance = function (name) {
        if (!this.instance) { // 判斷例項是否存在
            this.instance = new Singleton(name)
        }
        return this.instance
    }
    // 或者 getInstance 也可以用另一種方式實現
    Singleton.getInstance = (function () {
        var instance = null
        return function (name) {
            if (!instance) {
                instance = new Singleton(name)
            }
            return instance
        }
    })();
    
    // 呼叫
    var a = Singleton.getInstance('a')
    var b = Singleton.getInstance('b')
    
    console.log(a === b) // true
複製程式碼

上面程式碼中getInstance方法用了兩種不同方式實現,但是原理都是一樣的,只不過是一個把例項屬性放在本例項內,一個是利用閉包放在區域性變數中。

這樣寫的方式有一個缺點,就是和正常的生成例項方法不一樣,讓人不容易理解

正常生成例項方法

    var CreateDiv = (function () {
        var instance = null;
        var CreateDiv = function (html) {
            if (instance) {
                return instance
            }
            this.html = html;
            this.init();
            
            return instance = this;
        };
        
        CreateDiv.prototype.init = function () {
            var div = document.createElement('div');
            div.innerHTML = this.html;
            document.body.append(div);
        }
        
        return CreateDiv
        
    })();

複製程式碼

這種方法雖然能夠以new 去生成單例,但是建立物件和保證單例耦合在了一起,不符合單一職責原則。所以還要改

用代理實現單一模式

    var CreateDiv = function (html) {
        this.html = html;
        this.init();
    }
    
    CreateDiv.prototype.init = function () {
        var div = document.createElement('div');
        div.innerHTML = this.html;
        document.body.append(div);
    }
    
    var ProxySingletonCreateDiv = (function () {
        var instance;
        return function (html) {
            if (!instance) {
                instance = new CreateDiv(html);
            }
            return instance;
        }
    })();
複製程式碼

通過代理模式,創造物件和保證單例的方法分開,更易擴充套件

惰性單例

    var createLoginLayer = function () {
        var div = document.createElement('div');
        div.innerHTML = '我是登入浮窗';
        div.style.display = 'none';
        document.body.appendChild(div);
        return div;
    }
    
    var getSingle = function (fn) {
        var result;
        return function () {
            return result || (result = fn.apply(this, arguments));
        }
    }
    
    var createSingleLoginLayer = getSingle(createLoginLayer);
    // 當需要呼叫的時候 再呼叫這個方法
複製程式碼

惰性單例的優點可以當我需要的再去建立這個單例,而不是頁面已載入就建立。

相關文章