前言
在将函数作为一等对象的Javascript中,没有类的概念,设计模式相对于传统的面向对象有所区别
单例模式
单例模式是一个类只有一个实例的模式,比如线程池、DAO(数据库访问对象等),都不需要每次新创建一个实例
传统面向对象单例模式的创建
public class BlogDAO implements DAO<BlogORM>{
private BlogDAO(){};
public static BlogDAO instance = null;
static BlogDAO getInstance(){
if(instance==null){
instance = new BlogDAO();
}
return instance;
}
}
有个缺点就是用户必须知道使用getInstance
的方式获取实例,而我们更希望使用传统的方式获取单例模式,而这些在函数作为一等公民的Javascript是非常简单的。
普通的单例模式创建同上,但是我们想要的并不是这样
透明单例模式
const Single = (function(){
let instance = null;
return function(){
if(!instance){
instance = this;
}
return instance;
}
})()
const a = new Single('a');
const b = new Single('b');
console.log(a===b)// true
代理模式
上述模式创建单例模式也有个缺点,就是创建单例模式与Single类强耦合了,比如我们现在又不想创建单例模式了,就要返回去修改更改Single内部代码,这在设计模式中是不好的,需要遵循的是把不变与变化的部分分离开、面向AOP编程(面向切面编程,逻辑业务与不想关的部分分离开)、单一职责原则(一个对象或者函数内部只干同一件事)1。代理模式可以解决这个缺点
const Single = function(){}
const ProxySingle = (function(){
let instance = null;
return function(fn){
if(!instance){
instance = new fn();
}
return instance
}
})()
const a = new Single('a');
const b = new Single('b');
console.log(a===b);// false
const proxyA = new ProxySingle(Single);
const proxyB = new ProxySingle(Single);
console.log(proxyA===proxyB);// false
将创建过程与类分离开
Javacsript中的单例模式
Javascript处处都是对象,其实创建单例模式是非常简单的,一个对象字面量就是一个单例,我们基本时时刻刻都在使用它,不需要新创建一个类,做多余的步骤
const Single = {};
惰性单例
惰性单例就是不使用时不创建,只有真正的使用的时候才进行创建,其实getInstance的例子就是惰性单例的例子。
单例模式的用处
很多时候需要创建一次的地方都可以使用单例模式,不只是创建实例的地方,不要被局限了