惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
S
Securelist
MyScale Blog
MyScale Blog
Jina AI
Jina AI
罗磊的独立博客
The Cloudflare Blog
美团技术团队
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
博客园 - 三生石上(FineUI控件)
月光博客
月光博客
雷峰网
雷峰网
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
博客园 - Franky
博客园 - 聂微东
Y
Y Combinator Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MongoDB | Blog
MongoDB | Blog
T
Tailwind CSS Blog
Attack and Defense Labs
Attack and Defense Labs
博客园_首页
Latest news
Latest news
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Hacker News
The Hacker News
G
GRAHAM CLULEY
Simon Willison's Weblog
Simon Willison's Weblog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
U
Unit 42
D
Docker
Webroot Blog
Webroot Blog
N
Netflix TechBlog - Medium
T
Tor Project blog
C
Cyber Attacks, Cyber Crime and Cyber Security
L
LINUX DO - 最新话题
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The Last Watchdog
The Last Watchdog
B
Blog
Recent Announcements
Recent Announcements
GbyAI
GbyAI
Microsoft Azure Blog
Microsoft Azure Blog
Security Latest
Security Latest
V2EX - 技术
V2EX - 技术
N
News | PayPal Newsroom
Microsoft Security Blog
Microsoft Security Blog

博客园 - bala001

【记录】一文搞懂pinia状态管理(保姆级教程) 前端开发设计模式:原型模式 2025 年前端面试中常见问题 Object.create 前端开发设计模式:工厂模式(Factory Pattern)【下】 前端开发设计模式:工厂模式(Factory Pattern)【上】 前端开发设计模式:架构 前端开发设计模式: 单例模式(Singleton Pattern) JS篇之JS类型 2024/10/20: TypeScript 学习笔记三:TypeScript 类型系统 博文阅读密码验证 - 博客园 2024/09/22:TypeScript 学习笔记二 2024/09/20: TypeScript 学习笔记一 css 技巧 博文阅读密码验证 - 博客园 博文阅读密码验证 - 博客园 45 个每个开发人员都应该知道的 JavaScript 超级技巧 - 抄录 明确学习路径与方法 开篇词 - 《重学前端》
前端开发设计模式:单例模式之场景应用&实现
bala001 · 2025-03-14 · via 博客园 - bala001

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

常见场景

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 来设置、获取和删除缓存数据,保存了缓存数据的一致性和高效管理。