1.介绍
单例模式(Singleton Pattern)是设计模式中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
简而言之:就两点
- 系统中被唯一使用
- 一个类只有一个实例
单例模式思想在项目中经常体现到,例如,登录框,购物车等,这些都必须只有一个实例,总不能 弄了两个登录框,最后同时登陆了两个账号 进去吧。
看下 传统的 UML图
UML 图 有点晦涩难懂?不急,来看下简单粗暴的代码演示
2.代码演示
我们举个生活中的栗子,算了,不举栗子了,举个女朋友来讲好了,正常来讲,好男孩的女朋友 就是一个单例模式,当然,如果多个 势必会造成麻烦,当然如果你非得说你破碎的心爱上了不同的女孩,而且和她们的关系处理的非常好,那我只能说
好了,是时候亮出代码了
class Girl { //一个女孩的类,你可以在众多女孩中,寻找你的真爱}//话不多说,赶紧找个女朋友
Girl.getAGirlFriend = (function () {let girlFriend;return function () {if (!girlFriend){girlFriend = new Girl(); //恭喜你,成功脱单,生成一个女朋友成功}else {//你已经有女朋友啦,就不再创造了,下面返回的 还是你 的 现任}return girlFriend;}
})();//测试let girlFriend1 = Girl.getAGirlFriend(); // 生成一个女朋友
let girlFriend2 = Girl.getAGirlFriend();// 你企图再生成 一个女朋友//但是发现其实 生成的是同一个女朋友
//可以看看验证
console.log(girlFriend1 === girlFriend2); //打印结果为:true
可能基础不大好的同学,看到那么多括号,会感到头晕目眩的,其实这是用到了闭包的知识
,如果不用闭包的话,代码是这样的
//话不多说,赶紧找个女朋友
Girl.getAGirlFriend = function () {let girlFriend;return function () {if (!girlFriend){girlFriend = new Girl(); //恭喜你,成功脱单,生成一个女朋友成功}else {//你已经有女朋友啦,就不再创造了,下面返回的 还是你 的 现任}return girlFriend;}
};
这样就看起来容易理解一些,但是这样会出现一个错误
就你
let girlFriend1 = Girl.getAGirlFriend(); // 生成一个女朋友
的时候,获得的是
function () {if (!girlFriend){girlFriend = new Girl(); //恭喜你,成功脱单,生成一个女朋友成功}else {//你已经有女朋友啦,就不再创造了,下面返回的 还是你 的 现任}return girlFriend;}
是这个还没有执行的方法
你必须使用闭包来让这个方法自动执行。
可能没接触过闭包的同学还是难以理解,推荐可以看一下 我的另一篇文章 详解js闭包。
3.应用场景
3.1.模拟登录框
利用单例模式思想 来实现 登录框的 显示和隐藏
下面这段 是不是似曾相识的感觉
测试一下
let login1 = LoginForm.getInstance();
login1.show(); //打印:登录框显示成功let login2 = LoginForm.getInstance();
login2.hide(); //打印:登录框隐藏成功
可见 ,login1 和login2 是同一个实例
可以再测试一下
let login1 = LoginForm.getInstance();
login1.show(); //打印:登录框显示成功let login2 = LoginForm.getInstance();
login2.show(); //弹窗:已经显示
又 证实了 login1和login2是同一个实例
2.其他应用场景
- 购物车(和登录框类似)
- vuex和redux中的store 。相信学过vuex和redux的同学 已经感受到了 这种全局状态管理其实就是单例模式(),由于不方便演示,就不代码演示了,毕竟学过vuex自然懂了,而没学过的,演示出来,看代码也是一脸懵逼,把读者搞懵逼,这可不是我的作风啊。