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 里面存储的是应用中共享的状态数据,肯定是单例模式,比如登录状态,在整个应用中可能有很多地方会使用到登录状态,每个模块中获取到的登录状态一定时同一个

购物车

数据库连接

 

posted @ 2015-10-27 14:23  胡椒粉hjf  阅读(403)  评论(0编辑  收藏  举报