# 单例模式

# 介绍

  • 系统中被唯一使用
  • 一个类只有一个实例

# 示例

  • 登录框
  • 购物车

# 说明

  • 单例模式需要用到java的特性(private)
  • ES6 中没有(ts除外)
  • 只能用java代码来演示 UML 图的内容

java代码演示

public class SingleObject {
  // 注意,私有化构造函数,外部不能 new,只能内部new
  private SingleObject() {

  }
  // 唯一被 new 出来的对象
  private SingleObject instance = null
  // 获取对象的唯一接口
  public SingleObject getInstance() {
    if (instance === null) {
      // 只 new 一次
      instance = new SingleObject()
    }
    return instance
  }
  // 对象方法
  public void login(username, password) {
    System.out.printIn("login...")
  }
}

// 测试代码
public class SingletonPatterDemo {
  public static void main(String[] args) {
    // 不合法的构造函数
    // 编译时错误:构造函数SingleObject是不可见的
    // SingleObject object = new SingleObject()
    
    // 获取唯一可用的对象
    SingleObject object = SingleObject.getInstance()
    object.login()
  }
}

js代码演示

class SingleObject {
  login() {
    console.log('login...')
  }
}
SingleObject.getInstance = (function() {
  let instance
  return function() {
    if(!instance) {
      instance = new SingleObject()
    }
    return instance
  }
})()

// 测试
let obj1 =  SingleObject.getInstance()
obj1.login()
let obj2 =  SingleObject.getInstance()
obj2.login()

console.log('obj1 === obj2', obj1 === obj2)
// obj1 === obj2 true

# 场景

# jQuery 只有一个 $

// jQuery 只有一个 $
if(window.jQuery != null) {
  return window.jQuery
} else {
  // 初始化
}

# 模拟登录框

class LoginForm {
  constructor() {
    this.state = 'hide'
  }
  show() {
    if(this.state === 'show') {
      console.log('已经显示')
      return
    }
    this.state = 'show'
    console.log('登录框显示成功')
  }
  hide() {
    if(this.state === 'hide') {
      console.log('已经隐藏')
      return
    }
    this.state = 'hide'
    console.log('登录框隐藏成功')
  }
}

LoginForm.getInstance = (function() {
    let instance
    return function() {
      if(!instance) {
        instance = new LoginForm()
      }
      console.log(instance)
      return instance
    }
  })()

// 测试
let login1 = LoginForm.getInstance()
login1.show()

let login2 = LoginForm.getInstance()
login2.hide()
console.log('login1 === login2', login1 === login2)

# 其他

  • 购物车(和登录框类似)
  • vuex 和 redux 中的 store

# 设计原则验证

  • 符合单一职责原则,只实例化唯一的对象
  • 没法具体开放封闭原则,但是绝对不违反开放封闭原则

评 论:

更新: 11/21/2020, 7:00:56 PM