编程 JavaScript设计模式:单例模式

2024-11-18 10:57:41 +0800 CST views 558

JavaScript设计模式:单例模式

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

核心思想

  1. 唯一性:保证一个类只有一个实例。
  2. 全局访问点:提供一种方式来获取这个唯一的实例。

通常用于管理共享资源,如配置信息、线程池、缓存等。

模式结构

  • Singleton(单例类):包含一个私有静态变量来持有类的唯一实例,并提供一个公有静态方法来获取这个实例。

代码实现

类实现方式

class Singleton {
  static instance = null;

  constructor() {
    // 私有构造函数,防止外部实例化
  }

  static getInstance() {
    if (!Singleton.instance) {
      // 确保只创建一个实例
      Singleton.instance = new Singleton();
    }
    return Singleton.instance;
  }

  doSomething() {
    console.log("Doing something...");
  }
}

// 获取单例对象并调用方法
const singleton = Singleton.getInstance();
singleton.doSomething();

// 再次获取单例对象,将得到同一个实例
const anotherInstance = Singleton.getInstance();
console.log(singleton === anotherInstance); // 输出 true
  • 通过 Singleton.getInstance() 方法,无论何时调用,都会返回同一个实例。
  • 单例对象的创建是延迟的,即在第一次调用 getInstance() 方法时才创建。

闭包实现方式

const Singleton = (function () {
  let instance;

  function init() {
    // 私有变量和方法
    const privateMethod = function () {
      console.log("Private method");
    };

    return {
      publicMethod: function () {
        console.log("Public method");
        privateMethod();
      },
    };
  }

  return {
    getInstance: function () {
      if (!instance) {
        instance = init();
      }
      return instance;
    },
  };
})();

// 获取单例对象并调用方法
const singleton = Singleton.getInstance();
singleton.publicMethod();

// 再次获取单例对象,将得到同一个实例
const anotherInstance = Singleton.getInstance();
console.log(singleton === anotherInstance); // 输出 true

模式效果

优点

  1. 资源节约:由于只有一个实例,避免了频繁创建和销毁对象,节约系统资源。
  2. 一致性:确保系统中数据的一致性。
  3. 控制全局访问:可以控制实例的访问方式,保证系统中只有一个共享实例。

缺点

  1. 全局状态:单例模式可能会导致全局状态的维护,增加测试和维护的难度。
  2. 扩展性:由于只能创建一个实例,可能会限制类的扩展。
  3. 多线程问题:在多线程环境中需要额外的处理来保证线程安全(尽管 JavaScript 是单线程的,但要注意在其他语言中的并发问题)。

应用场景

  1. 系统只需要一个实例,如配置文件读取器、数据库连接池、日志管理器等。
  2. 需要一个全局访问点来获取唯一的实例。

模式应用

1. jQuery

jQuery 虽然不是真正的单例模式,但它在使用中表现出单例模式的特点:

  • 全局访问点:通过 $ 符号或 jQuery 提供了全局访问点。
  • 唯一实例:无论何时调用 jQuery()$(),都会返回相同的 jQuery 对象。
// 使用 jQuery 选择 DOM 元素
const myjQueryObject = $("<div>Hi, I'm a jQuery object!</div>");

// 全局访问 jQuery 对象
console.log(jQuery); // 输出 jQuery 对象
console.log($); // 输出 jQuery 对象

2. Pinia

Pinia 是 Vue 3 的官方状态管理库,展示了单例模式的特性:

  • 单个 Store 实例:每个通过 defineStore 创建的 Store 都是一个单例。
  • 全局状态访问:Pinia 提供 useStore 钩子,允许在应用的任何组件中访问同一个 Store 实例。
// 定义 Store
export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  getters: {
    double: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++;
    },
  },
});

// 使用 Store
<script setup>
import { useCounterStore } from '@/stores/counter';
const store = useCounterStore();
</script>

总结

单例模式确保类的实例唯一性,并提供一个全局访问点。它适用于需要全局共享资源的场景,如配置管理器、数据库连接池等。然而,单例模式也可能导致全局状态难以管理、扩展性受限的问题。在 JavaScript 的很多库中(如 jQuery、Pinia),我们可以看到单例模式的实际应用。

单例模式优缺点明显,需要在使用时结合实际需求权衡利弊。

复制全文 生成海报 设计模式 JavaScript 编程

推荐文章

如何在 Vue 3 中使用 Vuex 4?
2024-11-17 04:57:52 +0800 CST
Vue中的异步更新是如何实现的?
2024-11-18 19:24:29 +0800 CST
介绍Vue3的静态提升是什么?
2024-11-18 10:25:10 +0800 CST
微信小程序热更新
2024-11-18 15:08:49 +0800 CST
Python设计模式之工厂模式详解
2024-11-19 09:36:23 +0800 CST
55个常用的JavaScript代码段
2024-11-18 22:38:45 +0800 CST
liunx宝塔php7.3安装mongodb扩展
2024-11-17 11:56:14 +0800 CST
thinkphp swoole websocket 结合的demo
2024-11-18 10:18:17 +0800 CST
支付轮询打赏系统介绍
2024-11-18 16:40:31 +0800 CST
MyLib5,一个Python中非常有用的库
2024-11-18 12:50:13 +0800 CST
windows安装sphinx3.0.3(中文检索)
2024-11-17 05:23:31 +0800 CST
Nginx rewrite 的用法
2024-11-18 22:59:02 +0800 CST
一键配置本地yum源
2024-11-18 14:45:15 +0800 CST
阿里云免sdk发送短信代码
2025-01-01 12:22:14 +0800 CST
WebSQL数据库:HTML5的非标准伴侣
2024-11-18 22:44:20 +0800 CST
动态渐变背景
2024-11-19 01:49:50 +0800 CST
MySQL数据库的36条军规
2024-11-18 16:46:25 +0800 CST
Vue3中如何处理状态管理?
2024-11-17 07:13:45 +0800 CST
程序员茄子在线接单