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

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

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 编程

推荐文章

Elasticsearch 的索引操作
2024-11-19 03:41:41 +0800 CST
Golang - 使用 GoFakeIt 生成 Mock 数据
2024-11-18 15:51:22 +0800 CST
Linux 网站访问日志分析脚本
2024-11-18 19:58:45 +0800 CST
如何在 Vue 3 中使用 TypeScript?
2024-11-18 22:30:18 +0800 CST
Golang 中你应该知道的 Range 知识
2024-11-19 04:01:21 +0800 CST
维护网站维护费一年多少钱?
2024-11-19 08:05:52 +0800 CST
api远程把word文件转换为pdf
2024-11-19 03:48:33 +0800 CST
php 连接mssql数据库
2024-11-17 05:01:41 +0800 CST
thinkphp分页扩展
2024-11-18 10:18:09 +0800 CST
实现微信回调多域名的方法
2024-11-18 09:45:18 +0800 CST
程序员茄子在线接单