JS 设计模式单例模式

  • Post author:
  • Post category:其他


旧的实现方式,通过必包和立即执行函数表达式。

var UserStore = (function(){
  var _data = [];

  function add(item){
    _data.push(item);
  }

  function get(id){
    return _data.find((d) => {
        return d.id === id;
    });
  }

  return {
    add: add,
    get: get
  };
}());

UserStore 被赋了一个立即执行函数的运行结果: 这个函数执行并返回了一个对象,通过对象暴露了两个函数方法。

同时避免了对数据 _data 的直接访问。

缺点:不能达到单例模式所要求的良好的 immutability 。其他代码可能会修改暴露的函数方法,活着是重写 UserStore 。

利用模块实现单例模式

利用 ES 6 新特性

  • 第一种: 对象字面量的形式

    const _data = [];

    const UserStore = {

    add: item => _data.push(item),

    get: id => _data.find(d => d.id === id)

    }

    Object.freeze(UserStore);

    export default UserStore;

优点: 可读性;

良好的 immutability: 因为 UserStore 是用 const 声明的, 所以其他代码不会重写和破坏它;

使用 Object.freeze() 方法保护 UserStore 的方法也不能被改变,同时不能给 UserStore 添加新的属性和方法;

良好的代码跟踪: 因为使用了 ES 6 模块导出语法, 可以明确在代码中饮用模块的位置

  • 第二种: class 语法

    class UserStore {

    constructor(){

    this._data = [];

    }

    add(item){

    this._data.push(item);

    }

    get(id){

    return this._data.find(d => d.id === id);

    }

    }

    const instance = new UserStore();

    Object.freeze(instance);

    export default instance;

对象字面量的 immutability 和 non-overridability

对象字面量是可以复制的,即使是 const 声明的, 也可以通过使用 Object.assign() 方法。

  • 第三种:

    class UserStore {

    constructor(){

    if(! UserStore.instance){

    this._data = [];

    UserStore.instance = this;

    }

    return UserStore.instance;

    }

    //rest is the same code as preceding example

    }

    const instance = new UserStore();

    Object.freeze(instance);

    export default instance;

确保单例模式不被其他代码破坏, 同时满足面向对象语言特性

利用引用 instance 类的实例,可以检查是否代码中已经初始化过一个 UserStore, 如果

已经存在,旧不会在创建新实例。


https://www.sitepoint.com/whats-so-bad-about-the-singleton/



版权声明:本文为pepping798原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。