单例模式,传说中最简单,最容易理解的设计模式
其实单例模式有很多方式去实现,下面我将书上所说一一展现
最简单的实现方式
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);
// 当需要调用的时候 再调用这个方法
惰性单例的优点可以当我需要的再去创建这个单例,而不是页面已加载就创建。