前端开发设计模式:单例模式之场景应用&实现

 

单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。

 

常见场景

1、全局状态管理

   在前端应用中,常需要管理全局状态,像用户登录信息,主体设置等。借助单例模式,能保证全局状态的唯一性和一致性。

在vue.js 项目中,使用单例模式创建一个全局状态管理对象

// state.js

// GlobalState 类用于管理全局状态,它通过保存用户和主题信息来维护应用的状态
class GlobalState {
  // 构造函数确保只有一个实例被创建,它初始化用户和主题状态
  constructor() {
    if (!GlobalState.instance) {
      this.user = null; // 初始用户状态为 null
      this.theme = "light"; // 初始主题为 light
      GlobalState.instance = this; // 保存实例
    }
    return GlobalState.instance; // 返回实例,防止新实例创建
  }

  setUser(user) {
    this.user = user;
  }

  setTheme(theme) {
    this.theme = theme;
  }
}

const globalState = new GlobalState();

Object.freeze(globalState); // 冻结实例以防止修改,确保状态管理的完整性

export default globalState;
// someone.vue
//
在组件中使用 import globalState from './state.js'; export default { created(){ globalState.setUser({name:'John Doe'}) globalState.setTheme('dark') } }

 解释:

  • GlobalState 类确保只有一个实例存在,在整个应用中,任何组件都可以通过引入 globalState 来访问和修改全局状态
  • Object.freeze() 是JS中的一个内置方法,用于冻结一个对象。所谓 “冻结”,意味着该对象的状态被固定,不能再对其进行修改,具体包括不能添加新属性、不能删除已有属性、不能修改属性的可枚举性、可配置性、可写性,以及不能修改属性的值。

 

 

2、日志记录器

  使用单例模式创建日志记录器,能保证所有日志信息都被集中处理。

:创建一个单例日志记录器。

// logger.js
class Logger {
  constructor() {
    if (!Logger.instance) {
      this.logs = [];
      Logger.instance = this;
    }
    return Logger.instance;
  }

  // 记录一条日志信息
  log(message) {
    this.logs.push(message);
  }
}

const logger = new Logger();
Object.freeze(logger);

export default logger;
// someone.vue  在组件中使用
import logger from "./logger.js";

export default {
  created() {
    logger.log("component created");
  },
};

解释Logger 类的实例是唯一的,在应用的任何地方调用 logger.log 方法,日志信息都会被记录到同一个数组中,方便后续查看和分析。

 

 

3、弹窗管理

  使用单例模式管理弹窗,可以避免同时出现多个相同类型的弹窗。

创建一个单例弹窗管理器。

// modalManager.js
class ModalManager { constructor() {
if (!ModalManager.instance) { this.modal = null; ModalManager.instance = this; } return ModalManager.instance; } openModal(modal) { if (!this.modal) { this.modal = modal; // 打开弹框的逻辑 } } closeModal() { if (this.modal) { // 关闭弹框的逻辑 this.modal = null; } } } const modalManager = new ModalManager(); Object.freeze(modalManager); export default modalManager;
//someone.vue  在组件中使用

import modalManager from "./modalManager.js";

export default {
  methods: {
    showModal() {
      modalManager.openModal("confirm Modal");
    },
    hideModal() {
      modalManager.closeModal();
    }
  }
};

解释ModalManager 类确保只有一个弹窗实例被管理。 在调用 openModal 方法,只有当当前没有打开的弹窗时才会打开新的弹窗,避免弹窗重叠的问题。

 

 

4、数据库连接

  前端使用 indexDB 等数据库时,为避免创建多个数据库连接导致资源浪费和冲突,可使用单例模式来管理数据库连接。

:创建一个单例的 indexDB 连接管理

// dbConnection.js
class DBConnection {
  constructor() {
    if (!DBConnection.instance) {
      this.db = null;
      this.initDB();
      DBConnection.instance = this;
    }
    return DBConnection.instance;
  }

  // 初始化数据库连接
  async initDB() {
    // 使用 indexedDB 创建一个名为 'myDB' 的数据库
    const request = indexedDB.open("myDB", 1);
    request.onsuccess = (event) => {
      this.db = event.target.result;
    };
    request.onerror = (event) => {
      console.error("Error opening database:", event.target.error);
    };
  }

  getDB() {
    return this.db;
  }
}

const dbConnection = new DBConnection();
Object.freeze(dbConnection);

export default dbConnection;
// someone.vue  在组件中使用

import  dbConnection from './dbConnection.js'

export default {
    async created(){
        const db = dbConnection.getDB()
        if(db){
            // 进行数据库操作
        }
    }
}

解释:在需要使用数据库时,通过 dbConnection.getDB() 方法获取连接,避免重复创建连接

 

 

5、缓存管理

  在前端开发中,为了提高性能,常会使用缓存来存储一些经常使用的数据。使用单例模式管理缓存,可以确保缓存的一致性和高效性。

:创建一个单例缓存管理器

// cacheManager.js
class CacheManager {
  constructor() {
    if (!CacheManager.instance) {
      this.cache = {};
      CacheManager.instance = this;
    }
    return CacheManager.instance;
  }

  set(key, value) {
    this.cache[key] = value;
  }
  get(key) {
    return this.cache[key];
  }
  remove(key) {
    delete this.cache[key];
  }
}

const cacheManager = new CacheManager();
Object.freeze(cacheManager);
export default cacheManager;
// someone.vue  在组件中使用
import cacheManager from "./cacheManager.js";

export default {
  created() {
    cacheManager.set("data", { name: "John" });
    const data = cacheManager.get("data");
    console.log(data);
  },
};

解释:CacheManager 类的实例是唯一的,在应用的任何地方都可以通过 cacheManager 来设置、获取和删除缓存数据,保存了缓存数据的一致性和高效管理。

posted on 2025-03-14 17:27  bala001  阅读(111)  评论(0)    收藏  举报

导航