【设计模式】单例模式---对象创建型模式
1,意图
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
2,动机
对一些类来说,只有一个实例是很重要的。比如操作系统里面只应该有一个文件系统,一个资源管理器。一个会计系统只能专注于一个公司,一个班级只能有一个正班长。
我们要如何保证一个类只有一个实例,并且能够被访问。限制创建新对象,我们限制构造函数的访问,这一步是可以的,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建(通过截取创建新对象的请求),并且它可以提供一个访问该实例的方法,这就是Singleton模式。但是只能仅限于java c++等面向对象语言,因为他们可以使用private关键字限制构造函数的调用。
实现:
因为没法私有化构造函数,我想的是参考书上的 构造函数里面throw new 一个Error对象,声明一个getInstance方法来返回一个类级别的对象(就是原型了,对应java里面可以暂且理解为静态成员)。
先这样写:
因为ts在prototype上面扩展 string 类型property 要用hack,转换出来的代码和我想的有差距,就直接上js代码:
function Singleton() {
throw new Error('cannot create new object')
}
Singleton.prototype.instance = {}
Singleton.prototype.getInstance = function(){ return this.instance }
这样其实是可以的,但是这样写毫无意义,因为不能实例化Singleton对象,只能这样
x = Singleton.prototype.getInstance()
y = Singleton.prototype.getInstance()
x === y //true
于是改了一下代码:
function Singleton() {
return this.instance;
}
Singleton.prototype.instance = {}; //or = Object.create(new Singleton())
但是这样外界可以随意更改该实例,我们将代码通过闭包的实践--》模块模式-module pattern来改进一下:
var SingletonClass = (function() {
function SingletonClass() {
//do stuff
}
SingletonClass.prototype.constructor = null;
var instance;
return {
getInstance: function() {
if (instance == null) {
instance = new SingletonClass();
instance.constructor = null;
// Hide the constructor so the returned objected can't be new'd...
// 是为了阻止在外部我们直接通过 new instance.contructor()来构造一个和返回实例有一样的构造函数的实例
// 但是我们仍然能通过instance的prototype.constructor 获取到 实例的构造函数, 所以加上了下面这一句
// SingletonClass.prototype.constructor = null
}
return instance;
}
};
})();
参考:simplest-cleanest-way-to-implement-singleton-in-javascript
singleton-pattern-in-nodejs-is-it-needed
《design pattern》3.5节