JS 设计模式单例模式

    xiaoxiao2023-03-24  2

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

    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/

    转载请注明原文地址: https://ju.6miu.com/read-1201711.html
    最新回复(0)