设计模式之------单例模式

单例模式的意义

单例模式(Singleton Pattern)是一种设计模式,其核心思想是确保一个类仅有一个实例,并提供全局访问点。它的意义包括:

  1. 资源优化‌:避免重复创建对象,节省内存和计算资源。
  2. 数据一致性‌:全局共享同一个实例,避免多实例导致状态不一致。
  3. 集中管理‌:适用于全局状态、共享资源或需要统一控制的场景(如配置管理、日志记录)。

使用场景

  1. 全局状态管理‌(如 Redux Store)。
  2. 共享组件‌(如模态框、提示框)。
  3. 工具类‌(如日志记录器、缓存管理)。

代码示例与详细讲解

示例 1:全局状态管理器

javascript 复制代码
class Store {
  static instance = null;

  // 通过静态方法获取单例
  static getInstance() {
    if (!Store.instance) {
      Store.instance = new Store();
    }
    return Store.instance;
  }

  constructor() {
    if (Store.instance) {
      throw new Error("Use Store.getInstance() instead of direct instantiation.");
    }
    this.state = {}; // 全局状态
  }

  // 更新状态
  setState(key, value) {
    this.state[key] = value;
  }

  // 获取状态
  getState(key) {
    return this.state[key];
  }
}

// 使用示例
const store1 = Store.getInstance();
const store2 = Store.getInstance();
console.log(store1 === store2); // true(证明是同一个实例)

store1.setState("user", "Alice");
console.log(store2.getState("user")); // "Alice"

讲解‌:

  • 通过 Store.getInstance() 获取单例,确保全局唯一。
  • 直接调用 new Store() 会抛出错误,防止误用。
  • 适用于需要统一管理全局状态的场景(如用户信息、主题配置)。

示例 2:模态框组件

ini 复制代码
class Modal {
  static instance = null;

  static getInstance() {
    if (!Modal.instance) {
      Modal.instance = new Modal();
    }
    return Modal.instance;
  }

  constructor() {
    if (Modal.instance) {
      throw new Error("Modal instance already exists.");
    }
    // 创建模态框 DOM 元素
    this.element = document.createElement("div");
    this.element.innerHTML = `
      <div class="modal" style="display: none;">
        <p>This is a modal!</p>
        <button>Close</button>
      </div>
    `;
    document.body.appendChild(this.element);
  }

  show() {
    this.element.style.display = "block";
  }

  hide() {
    this.element.style.display = "none";
  }
}

// 使用示例
const modal1 = Modal.getInstance();
const modal2 = Modal.getInstance();
console.log(modal1 === modal2); // true

modal1.show(); // 显示模态框
modal2.hide(); // 隐藏同一个模态框

讲解‌:

  • 模态框的 DOM 元素只需创建一次,避免重复渲染。
  • 通过单例确保全局只有一个模态框实例,防止页面中出现多个弹窗。
  • 适用于提示框、对话框等需要全局唯一组件的场景。

示例 3:日志记录器

javascript 复制代码
class Logger {
  static instance = null;

  static getInstance() {
    if (!Logger.instance) {
      Logger.instance = new Logger();
    }
    return Logger.instance;
  }

  constructor() {
    if (Logger.instance) {
      throw new Error("Logger instance already exists.");
    }
    this.logs = [];
  }

  log(message) {
    const timestamp = new Date().toISOString();
    this.logs.push({ message, timestamp });
    console.log(`[${timestamp}] LOG: ${message}`);
  }

  printLogHistory() {
    console.log("Log History:");
    this.logs.forEach(entry => console.log(`[${entry.timestamp}] ${entry.message}`));
  }
}

// 使用示例
const logger1 = Logger.getInstance();
const logger2 = Logger.getInstance();
logger1.log("User logged in"); // [时间戳] LOG: User logged in
logger2.log("Data fetched");   // [时间戳] LOG: Data fetched
logger1.printLogHistory(); // 输出两条日志记录

讲解‌:

  • 所有日志通过同一个实例记录,便于统一处理(如上传到服务器)。
  • 避免每次记录日志时创建新实例的开销。
  • 适用于需要集中管理日志、缓存、性能监控等工具类场景。

单例模式通过限制类的实例化次数,确保全局唯一性,适用于以下场景:

  1. 资源敏感型对象‌(如数据库连接池)。
  2. 需要共享状态的组件‌(如全局 Store)。
  3. 频繁访问的工具类‌(如日志记录器)。

相关推荐
天蓝色的鱼鱼1 小时前
前端开发者的组件设计之痛:为什么我的组件总是难以维护?
前端·react.js
codingandsleeping1 小时前
使用orval自动拉取swagger文档并生成ts接口
前端·javascript
石金龙2 小时前
[译] Composition in CSS
前端·css
白水清风2 小时前
微前端学习记录(qiankun、wujie、micro-app)
前端·javascript·前端工程化
Ticnix3 小时前
函数封装实现Echarts多表渲染/叠加渲染
前端·echarts
用户22152044278003 小时前
new、原型和原型链浅析
前端·javascript
阿星做前端3 小时前
coze源码解读: space develop 页面
前端·javascript
叫我小窝吧3 小时前
Promise 的使用
前端·javascript
NBtab3 小时前
Vite + Vue3项目版本更新检查与页面自动刷新方案
前端
天天扭码3 小时前
来全面地review一下Flex布局(面试可用)
前端·css·面试