为什么要讲模式,模式是一种思维,可以帮我们解决很多实践项目中的问题,例如之前的JavaScript设计模式之发布订阅模式就可以帮我们解决同一主模块下的不同子模块以及不同主模块之间的通信。推荐的库是tiny-emitter一个轻型的事件发射库。
JavaScript设计模式之单例模式就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。
es5实现单例模式
function Universe() {
// 判断是否存在实例
if (typeof Universe.instance === 'object') {
return Universe.instance;
}
// 其它内容
this.start_time = 0;
this.bang = "Big";
// 缓存
Universe.instance = this;
// 隐式返回this
}
// 测试
var uni = new Universe();
var uni2 = new Universe();
console.log(uni === uni2); // true
es6实现单例模式
class Universe{
static instance;
constructor(){
//判断是否存在实例
if(Universe.instance){
return Universe.instance;
}
// 其它内容
this.create();
//缓存
Universe.instance = this;
// 隐式返回this
}
create(){
.....
}
}
单例模式的使用场景
网上搜了一下大多是这样说的,在windows操作系统中,如Task Manager(任务管理器)我们是无法打开两个的,回收站也只能打开一个,这些其实就是单例模式的应用。对于开发人员来说以下几个场景也是:
1、网站计数器,一般是采用单例模式实现,否则难以同步。
2、由于配置文件一般都是共享资源,即web应用的配置对象的读取,一般采用单例模式来实现。如:spring的配置文件的读取等
3、多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
4、数据库连接池的设计也是采用单例模式的。数据库连接其实也是一种数据连接的共享资源,在jdbc连接中如果在做频繁操作的时候,不停的打开或者关闭会效能损耗,因此用单例模式来维护就大大降低了这种效能损耗。
使用单例模式应用的场景一般有两个条件:
1、资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的应用配置、数据连接池的设计。
2、控制资源的情况下,方便资源之间的互相通信。如多线程的线程池设计等。
所以,单例模式的适应场景如:
1、需要频繁实例化然后销毁的对象。
2、创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
3、有状态的工具类对象。
4、频繁访问数据库或文件的对象。
这些场景中单例模式带来好处是很明显的:
它在内存中只有一个实例,占用内存少;
避免了频繁创建销毁对象,提搞了性能;
避免了公共资源的重复占用,并且可以全局使用;
栗子:
每个弹窗都是一个实例对象
优化前:
每次点击都会重新创建一下实例对象及其所拥有的方法,耗资源;
每次点击都会重新创建弹窗内容,如手机号码等不能在下次点开时保留,即状态保留;
优化后:
实例对象调整为单例对象,多次点击无需多次重复创建对象及其方法,减少资源消耗;
弹窗内容,只在第一次创建对象时创建,保留状态;