【學習設計模式】通用的單例包裝器

1. 簡介

Singleton(單例)模式的理解要從兩個方面javascript

  1. 它限制了類的實例化次數只能爲一次,即在該實例不存在的狀況下,能夠經過一個方法建立對象實例,若是實例已經存在,則返回該對象的引用。java

  2. 它不一樣於靜態類(對象),單例能夠推遲初始化,這一點很重要,由於能夠推遲初始化,就意味着不用過早地爲單例分配內存資源,而是能夠當須要使用時,纔對其進行初始化,分配對應的內存空間。app

單例的存在,在一些時候並非好事,可能它的出現時由於系統中的模塊要麼是系統緊密耦合,要麼是其邏輯過度分散。ui

2. 代碼示例

var singleton = (function () {
    var instance;
    return {
        getInstance : function (factory){
            var args = Array.prototype.slice.call(arguments, 1);
            if(!instance){
                instance = {};
                factory.apply(instance, args);
            }
            return instance;
        }
    }
})();

代碼中建立了一個單例的包裝器,使用的示例代碼以下this

function Person(name, age){
    this.name = name;
    this.age = age;
    this.sayName = function () {
        console.log(this.name);
    }
}
var p1 = singleton.getInstance(Person, "zhang", 25);
var p2 = singleton.getInstance(Person);
console.log(p1 == p2); // true
console.log(p2.sayName()); // "zhang"

由於是單例,所以,咱們能夠把對象的方法直接放在this上,而不用放在Person的prototype對象上。可是這段代碼還有不足,那就是隻能產生一個構造器的單例,咱們能夠來對其進行改進。prototype

var singleton = (function () {
    var instances = [],
        guid = 0;
    return {
        getInstance : function (factory){
            var args = Array.prototype.slice.call(arguments, 1);
            if(typeof factory._guid == "undefined"){ 
                instances[guid] = {};
                factory.apply(instances[guid], args);
                factory._guid = guid++;
            }
            return instances[factory._guid];
        }
    }
})();

咱們能夠使用一個單例池(instances)來保存不一樣構造器的單例,用_guid來標識是否爲該構造器生成單例,並做爲下標索引獲取該單例。使用示例:code

function Person(name, age){
    this.name = name;
    this.age = age;
    this.sayName = function () {
        console.log(this.name);
    }
}

var p1 = singleton.getInstance(Person, "zhang", 25);
var p2 = singleton.getInstance(Person);
console.log(p1 == p2); // true
console.log(p2.sayName()); // "zhang"

function Car(brand){
    this.brand = brand;
    this.sayBrand = function () {
        console.log(this.brand);
    }
}

var c1 = singleton.getInstance(Car, "benchi");
var c2 = singleton.getInstance(Car);
console.log(c1 == c2); // true
console.log(c2.sayBrand()); // "benchi"
相關文章
相關標籤/搜索