共计 1980 个字符,预计需要花费 5 分钟才能阅读完成。
Singleton(单例模式)
Singleton(单例模式)属于创立型模式,提供一种对象获取形式,保障在肯定范畴内是惟一的。
用意:保障一个类仅有一个实例,并提供一个拜访它的全局拜访点。
其实单例模式在前端领会的不显著,起因有:
- 前端代码自身在单机运行,创立的任何变量都是人造分布式的,不须要放心影响另一个用户。
- 后端代码是一对多的,分辨出哪些资源是申请间共享的,哪些是申请内独有的很重要。
另外咱们说到单例,是隐含了一个范畴的,指的是在某个范畴内单例,比方在一个上下文中,还是一个房间中,还是一个过程,一个线程中单例,不同场景范畴会不同。
举例子
如果看不懂下面的用意介绍,没有关系,设计模式须要在日常工作里用起来,联合例子能够加深你的了解,上面我筹备了三个例子,让你领会什么场景下会用到这种设计模式。
多人游戏的共享物品
玩过游戏的同学都晓得,咱们在每局游戏中应用的公共物品在以后房间中是惟一的,但在游戏房间间却不是惟一的,所以这些公共物品必定有不同的类去形容,那每局游戏中怎么拿公共物品,能够保障拿到的是以后局内惟一的?
Redux 数据流
其实前端的 Redux 数据流自身就是单例模式,在一个利用中,数据是惟一的,但能够有不同的 UI 应用这份惟一的数据,甚至把一个表格组件展现在两个不同中央,比方全屏模式,但数据仍然是一份,咱们没有必要为了全屏展现表格,就让它再发一次取数申请,齐全能够和原来的表格共享一份数据。
数据库连接池
每个 SQL 查问都依赖数据库连接池,如果每次查问都建设一次数据库连接池,则建设连贯的速度会远远慢于 SQL 查问速度,因而你会怎么设计数据库连接池的获取办法?
用意解释
单例模式的用意很简略,简直就是其字面含意:
用意:保障一个类仅有一个实例,并提供一个拜访它的全局拜访点。
对于多人游戏的共享物品,比方一口锅,要保障在一局游戏内惟一,就要提供一种办法拜访到惟一实例。
Redux 数据流的 connect
装璜器就是全局拜访点的一种设计。
数据库连接池能够提前初始化好,并通过固定 API 提供这个惟一实例。
结构图
Singleton
是单例模式的接口,客户只能通过其定义的 instance()
拜访实例,以保障单例。
代码例子
上面例子应用 typescript 编写。
`class Ball {
private _instance = undefined
// 构造函数申明为 private,就能够阻止 new Ball() 行为
private constructor() {}
public static instance = () => {
if (this._instance === undefined) {
this._instance = new Ball()
}
return this._instance
}
}
// 应用
const ball = Ball.getInstance()
`
能够认真想想,为什么这个例子把单例写成了静态方法,而不是一个全局变量?其实全局变量也能解决问题,但因为会净化全局,要尽可能通过模块化形式解决,下面的例子就是一个较好的封装形式。
当然这只是一个最简略的例子,实际上单例模式还有几种模式:
饿汉式
初始化时就生成一份实例,这样调用时间接就能获取。
懒汉式
就是代码例子中写的,按需实例化,即调用的时候再实例化。
要留神,按需不肯定是什么坏事,如果 New 的老本很高还按需实例化,可能把零碎异样的危险留到随机的触发机会,导致难以排查 BUG,另外也会影响第一次实例化时的零碎耗时。
对 JAVA 来说,单例还须要思考并发性,有 双重检测、动态外部类、枚举 等方法解决,这里不具体开展。
弊病
单例模式的问题有:
- 对面向对象不太敌对。对封装、继承、多态反对不够敌对。
- 不利于梳理类之间的依赖关系。毕竟单例是间接调用的,而不是在构造函数申明的,所以要梳理关系要看完每一行代码能力确定。
- 可拓展性不好。万一要反对多例就比拟难拓展,比方全局数据流可能因为微前端计划改成多实例、数据库连接池为了分治 SQL 改成多实例,都是有可能的,在零碎设计之初就要思考到将来是否还会放弃单例。
- 可测试性不好,因为单例是全局共享的,无奈保障测试用例间的隔离。
- 无奈应用构造函数传参。
另外单例模式还能够被工厂办法所代替,所以不必特地纠结一种设计模式,能够联合应用,工厂函数也能够内嵌单例模式。
总结
单例模式概念、用法都简略,是架构设计罕用计划,但要充沛了解到单例模式的弊病,避免不失当的应用。
探讨地址是:精读《设计模式 – Singleton 单例模式》· Issue #278 · dt-fe/weekly
如果你想参加探讨,请 点击这里,每周都有新的主题,周末或周一公布。前端精读 – 帮你筛选靠谱的内容。
关注 前端精读微信公众号
版权申明:自在转载 - 非商用 - 非衍生 - 放弃署名(创意共享 3.0 许可证)