JavaScript 常见设计模式----单例模式

63 阅读1分钟

介绍

  • 一个对象/实例 只能被创建一次
  • 创建之后缓存起来,以后继续使用
  • 即,一个系统中只有一个

示例

  • 登录框,遮罩层,一个系统只有一个即可,多了无用
  • Vuex Redux的store,一个系统中只能有一个,多了会出错

UML类图

image.png

示例代码

使用TS特性

  • static 静态属性和方法(不能在类的实例上调用静态方法,而应该通过类本身调用)
  • private 外部无法直接初始化
class Singleton{
    //private -外部无法初始化
    private constructor(){}
    //static 属性
    private static instance:Singleton | null
    //static 方法
    static getInstance():Singleton {
        if(Singleton.instance == null){
            Singleton.instance = new Singleton()
        }
        return Singleton.instance
    }
}
//const s1 = new Singleton() // 直接初始化会报错
//Singleton.instance //直接访问instance 也会报错
//创建实例
const s1 = Singleton.getInstance()
const s2 = Singleton.getInstance()
console.log(s1 === s2) //true

不使用TS

function getGenInstance () {
  let instance //闭包
  class Singleton{ }
  return () => {
    if(instance == null) {
      instance = new Singleton()
    }
    return instance
  }
}
const getInstance = getGenInstance()
const s1 = getInstance()
const s2 = getInstance()
console.log(s1 === s2) // true
  • 符合开放封闭原则,对扩展开放,对修改封闭
  • 内部封装getInstance,内聚,解耦

使用场景

  • 自定义事件 EventBus 全局唯一
  • Vuex Redux 的store 全局唯一

注意事项

  • JS是单线程语言,如果是java等多线程语言,单例模式需要加线程锁
  • 前端对单例模式并不常用,但单例的思想随处可见