单例模式

28 阅读2分钟

实现基于LocalStorage的单例模式存储类

在现代Web开发中,尤其是在构建复杂的前端应用时,使用设计模式可以极大地提升代码的可维护性和效率。其中,单例模式是一种常用的模式,它保证一个类仅有一个实例,并提供一个全局访问点。

单例模式在Storage类中的实现

为了利用单例模式封装一个基于localStorage的存储类,我们首先定义了一个Storage类,该类包含静态方法getInstance,用于控制实例的创建和返回。下面是一个使用ES6类和静态成员变量的实现示例:

/**
 * @func 基于localStorage封装Storage类,单例模式
 * @author  Ro9nin
 * @date 2024-07-04
 */
// 语法糖
class Storage {
    // static instance;
    static getInstance() {
        // JS 动态  static 属性
        // JS 没有类,都是对象
        if (!Storage.instance) {
            Storage.instance = new Storage();
        }
        return Storage.instance;
    }

    getItem(key) {
        return localStorage.getItem(key);
    }

    setItem(key, value) {
        localStorage.setItem(key, value);
    }
}

// new Storage();

export default Storage

通过上述代码,无论何时调用Storage.getInstance(),都会返回同一个实例。这样,即使在应用程序的不同部分尝试创建Storage类的实例,最终也只会存在一个实例,从而避免了资源的浪费。

ES6模块化与导入

为了在现代Web环境中更好地组织代码,我们使用ES6模块化特性将Storage类导出,以便其他模块可以通过import语句来使用它。例如,在index.html文件中,我们可以通过<script type="module">标签或在JS文件中使用import语句来导入Storage类。

<script type="module">
    import Storage from './storage.js';
    const instance1 = Storage.getInstance();
    const instance2 = Storage.getInstance();
    console.log(instance1 === instance2); // 输出true,证明两个实例引用相同
</script>

使用IIFE实现单例模式

另一种实现单例模式的方法是使用立即执行函数表达式(IIFE)。这种方法不需要ES6的类,而是利用闭包来保存实例。以下是使用IIFE实现的Storage类:

function StorageBase(){

}

StorageBase.prototype.getItem = function(key){
    return localStorage.getItem(key);
}

StorageBase.prototype.setItem = function(key, value){
    return localStorage.setItem(key, value);
}

const storage = (function(){
    let instance = null
    return{
        getInstance(){
            if(!instance){
                instance = new StorageBase()
            }
            return instance
        }
    }
}) ()

在这个实现中,storage对象提供了一个getInstance方法,用于获取StorageBase类的唯一实例。由于instance变量被封闭在IIFE的作用域内,所以它不会被外部环境所污染,从而确保了单例的特性。

    <script src="./old_storage.js"></script>
    <script>
    const instance1  = Storage.getInstance()
    const instance2  = Storage.getInstance()
    console.log(instance1 === instance2)
    </script>

无论是使用ES6类还是IIFE,单例模式都是一个强大且实用的设计模式,尤其在需要控制资源或状态的单一全局访问点时。通过上述实现,我们可以轻松地在Web应用中集成基于localStorage的单例存储服务,以提高应用的性能和响应性。