JavaScript设计模式—单例模式
单例模式介绍
系统中被唯一使用的,一个类只有一个实例
单例模式的思路是:
一个类能返回一个对象的引用(并且永远是同一个)和一个获得该实例的方法(静态方法,通常使用 getInstance 名称)。
那么当我们调用这个方法时,如果类持有的引用不为空就返回该引用,否者就创建该类的实例,并且将实例引用赋值给该类保持的那个引用再返回。
同时将该类的构造函数定义为私有方法,避免其他函数使用该构造函数来实例化对象,只通过该类的静态方法来得到该类的唯一实例。
UML类图和代码示例
这里是根据Java代码画的UML类图,跟js的代码不一样但是思路是一样的
单例模式需要使用到Java的特性(private),在ES6中是没有这样修饰符的(typescript除外),所以只能使用Java代码来演示
在js中可以使用闭包来实现单例模式,但是没法将类的构造函数私有化,后面综合应用中会使用到模块化解决这个问题
class SingleObject { login () { console.log('login.....') } } SingleObject.getInstance = (function () { let instance // 外层函数定义一个唯一的变量 return function () { if (!instance) { instance = new SingleObject() } return instance } })() // 测试:注意这里只能使用静态函数getInstance,不能new SingleObject() let obj1 = SingleObject.getInstance() obj1.login() let obj2 = SingleObject.getInstance() obj2.login() console.log(obj1 === obj2) //true // 我们不能避免的是:js不能像Java那样将构造函数私有化,别人不知道我们代码的情况下 // 有可能直接使用new SingleObject
设计原则验证
符合单一职责原则,只能实例化唯一的一个对象
没有特别的体现开发封闭原则,但是绝对不违反开放封闭原则
场景示例
Jquery只有一个$
// Jquery只有一个$ if (window.jQuery != null) { return window.jQuery } else { // 初始化 }
模拟登录框
class loginFrom { constructor () { this.state = 'hide' } show () { if (this.state === 'show') { console.log('已经显示') return } this.state = 'show' console.log('登录框已显示') } hide () { if (this.state === 'hide') { alert('已经隐藏') return } this.state = 'hide' console.log('登录框已隐藏') } } loginFrom.getInstance = (function () { let instance return function() { if (!instance){ instance = new loginFrom() } return instance } })() // 测试 let login1 = loginFrom.getInstance() login1.show() let login2 = loginFrom.getInstance() login2.show() console.log(login1 === login2) //true
vuex和redux中的store
vuex和redux中的store 里面存储的是应用中共享的状态数据,肯定是单例模式,比如登录状态,在整个应用中可能有很多地方会使用到登录状态,每个模块中获取到的登录状态一定时同一个
购物车
数据库连接