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

单例模式的意义

单例模式(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. 频繁访问的工具类‌(如日志记录器)。

相关推荐
2601_949817929 分钟前
大厂Java进阶面试解析笔记文档
java·笔记·面试
猫猫不是喵喵.1 小时前
layui表单项次大数据量导入并提交
前端·javascript·layui
张小潇1 小时前
AOSP15 WMS/AMS系统开发 - 窗口层级源码分析
android·前端
C雨后彩虹1 小时前
最多等和不相交连续子序列
java·数据结构·算法·华为·面试
whuhewei1 小时前
HTTP1/2/3演变
前端·计算机网络
腹黑天蝎座1 小时前
从零实现一个前端监控系统:性能、错误与用户行为全方位监控
前端·监控
一江寒逸1 小时前
零基础从入门到精通 AI Agent 开发(全栈保姆级教程)附加篇:AI Agent 面试八股文全集
人工智能·面试·职场和发展
爱敲代码的小黄1 小时前
我重新梳理了一遍 RAG,终于明白它不只是接个向量库
后端·面试·agent
久菜盒子工作室2 小时前
面试经验|产品经理|自我介绍
面试·职场和发展·产品经理
Hello--_--World2 小时前
ES13:类私有属性和方法、顶层 await、at() 方法、Object.hasOwnProperty()、类静态块 相关知识点
开发语言·javascript·es13