JS设计模式--单例模式

单例模式的定义是:保证一个类仅有一个实例,并提供一个访问他的全局点。

我们经常在开发中遇到这种情况,比如要弹出一个页面上唯一的对话框,此时,单例模式节能很好地完成这个任务。

1.实现单例

比如我们需要实现一个类的唯一实例:

var Me = function(name, age) {
    this.name = name;
    this.age = age;
};

Me.prototype.getName = function() {
    return this.name;
};

Me.getInstance = (function() {
    var instance;

    return function(name, age) {
        if (!instance) {
            return instance = new Me(name, age);
        }
        return instance;
    }
})();

var me1 = Me.getInstance('zyt', '24');
var me2 = Me.getInstance('tyz', '100');

me1 === me2; // true

以上就创建了一个唯一的实例。

2.简单单例

为了在页面上用js动态地创建一个弹出框(div),可以做以下的尝试:

var createDiv = (function() {
    var instance;

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

    return Div;
})();

var div1 = new createDiv('1111');
var div2 = new createDiv('2222');

div1 === div2; // true

以上代码没有遵循单一职责原则,将所有的类、方法封在一个函数之中,增加了程序的复杂度。

3.惰性单例

惰性单例是指在需要的时候才创建对象实例。还是创建div:

var createDiv = (function() {
    var div;
    return function() {
        if (!div) {
            div = document.createElement('div');
            div.innerHTML = '你猜';
            document.body.appendChild(div);
        }
        return div;
    };
})();

document.onclick = function() {
    createDiv();
};

多次点击也只会创建一个div了。

4.通用单例

为了遵循单一职责原则和增加代码的复用,做出了改进。

首先将管理单例的逻辑抽离出来:

var getSingle = function(fn) {
    var result;
    return function() {
        return result || (result = fn.apply(this, arguments));
    };
};

创建div的逻辑代码就变成以下:
var oDiv = function() {
    var div = document.createElement('div');
    div.innerHTML = '我是谁?';
    document.body.appendChild(div);
    return div;
};

var createDiv = getSingle(oDiv);

document.onclick = function() {
    createDiv();
};

此时,多次点击也不会创建多个div。而这样的好处就是以后如果创建的不是div,而是其他的元素,getSingle()函数也同样能适用,只需修改创建的逻辑代码。

 

发表评论