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

单例模式的意义

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

相关推荐
golang学习记几秒前
刚刚,OpenAI首个AI浏览器发布!颠覆Chrome,彻底改变你上网的方式|附实测
前端
吃饺子不吃馅7 分钟前
项目上localStorage太杂乱,逼我写了一个可视化浏览器插件
前端·javascript·chrome
golang学习记8 分钟前
从0 死磕全栈之Next.js 环境变量实战指南:企业级多环境(dev/test/prod)配置最佳实践
前端
绝无仅有9 分钟前
猿辅导面试系列:MQ消息队列解析与常见面试问题
后端·面试·github
绝无仅有15 分钟前
猿辅导计算机面试文章经典总结
后端·面试·github
.生产的驴34 分钟前
React 集成Redux数据状态管理 数据共享 全局共享
前端·javascript·react.js·前端框架·css3·html5·safari
IT_陈寒36 分钟前
Redis性能优化的7个隐藏技巧:从慢查询到亿级QPS的实战经验分享
前端·人工智能·后端
艾小码1 小时前
ES6+革命:8大特性让你的JavaScript代码质量翻倍
前端·javascript
两个西柚呀1 小时前
Vue组件的一些底层细节
前端·javascript·vue.js
IT技术分享社区1 小时前
前端:浏览器Content Security Policy 安全策略介绍和用法
前端·前端开发