单例模式

86 阅读3分钟

什么是单例模式?

又称单体模式(同样也是创建型设计模式),一种设计模式、目的是确保一个类只有一个实例,并且提供一个全局访问点。

在单例模式中,类有一个私有构造函数,防止类被实例化多次;单例模式的实现涉及到以下几个关键点:

  1. 私有构造函数(Private Constructor): 单例类通常有一个私有的构造函数,防止通过 new 操作符来实例化多个对象。

  2. 私有静态变量(Private Static Variable): 类内部维护一个私有的静态变量,用于存储类的唯一实例。

  3. 静态方法(Static Method): 提供一个静态方法来获取类的唯一实例。这个方法会负责创建实例(如果实例不存在),并返回该实例。

  4. 延迟实例化(Lazy Instantiation): 有时候,实例只有在第一次请求时才会被创建。这种方式被称为延迟实例化,有助于减少启动时间和资源占用。

单例模式示例:

class Singleton {
  //new对象会首先执行构造函数中的代码
  constructor() {
    // 私有构造函数,防止通过 new 操作符实例化多个对象
    if (typeof Singleton.instance === 'object') {
      return Singleton.instance;
    }

    // 正常的初始化操作
    this.property1 = 'some value';
    this.property2 = 'another value';

    // 将实例存储在静态变量中
    Singleton.instance = this;

    // 返回实例
    return this;
  }

  // 静态方法,用于获取实例
  static getInstance() {
    if (typeof Singleton.instance === 'object') {
      return Singleton.instance;
    }

    return new Singleton();
  }
}

// 使用单例模式
const instance1 = new Singleton();
const instance2 = new Singleton();

console.log(instance1 === instance2); // true,因为只创建了一个实例

const instance3 = Singleton.getInstance();
const instance4 = Singleton.getInstance();

console.log(instance3 === instance4); // true,通过静态方法获取的实例也是同一个实例

常见的使用场景

  1. 全局状态管理: 在应用中维护全局的状态信息,确保整个应用共享同一份状态数据。常见的前端状态管理库(如Redux、Vuex)内部就使用了单例模式,确保全局状态的一致性。

  2. 配置管理: 用于管理应用的配置信息,例如主题、语言、API 地址等。通过单例模式,可以确保在整个应用中只有一个配置对象,避免多处配置的冗余和不一致性。

  3. 工具类的封装: 在前端开发中,有些工具类只需要一个实例,例如日志记录器、缓存管理器等。通过单例模式,可以确保这些工具类只被实例化一次,避免重复创建。

  4. 模块管理: 在一些前端框架或库中,使用单例模式来管理模块,确保每个模块只被实例化一次,提高模块的复用性和性能。

  5. 事件总线: 单例模式常被用于创建一个全局的事件总线,用于组件之间的通信。通过事件总线,可以实现解耦和简化组件之间的通信流程。

  6. HTTP请求管理: 在处理网络请求时,有时候需要一个统一的管理器来处理请求的拦截、缓存、超时等逻辑。通过单例模式,可以确保整个应用共享同一个请求管理器。

  7. 路由管理: 在一些前端框架中,路由管理器常常使用单例模式,确保整个应用只有一个路由实例,方便统一管理导航和页面跳转。

  8. 全局对象的创建: 某些情况下,需要在应用中创建一个全局唯一的对象,例如地图对象、WebGL 上下文等。通过单例模式,可以确保只有一个实例存在。

需要注意的是,在使用单例模式时,要确保它的使用是合理的,不要过度使用,因为全局状态的增加可能导致应用的复杂性增加。合理的使用单例模式可以简化代码结构、提高代码的可维护性和性能。