概念

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

单例模式通过将类的构造函数设为私有,防止外部直接创建实例,同时提供一个静态方法或者属性来获取该实例,从而保证在整个应用程序中只有一个实例存在


单例模式的核心思想是确保一个类只有一个实例存在,并提供一个全局访问点来访问该实例

这种模式的优点在于,可以节省系统资源,提高系统性能,同时也可以保证全局访问点的一致性


然而,需要注意的是,单例模式可能会引入全局状态,增加了代码的耦合度,降低了代码的可测试性

因此,在使用单例模式时需要谨慎考虑


举个简单的例子,考虑一个日志记录器

无论在应用程序的任何地方都需要记录日志,而且只需要一个日志记录器实例来处理所有的日志记录任务

使用单例模式,可以确保在整个应用程序中只有一个日志记录器实例存在,从而实现日志记录的统一管理和控制


实现条件

  1. 单例类的构造函数必须是私有的,这样才能将类的创建权控制在类的内部,从而使得类的外部不能创建类的实例。
  2. 单例类通过一个私有的静态变量来存储其唯一实例。
  3. 单例类通过提供一个公开的静态方法,使得外部使用者可以访问类的唯一实例

注意:

因为单例类的构造函数是私有的,所以单例类不能被继承


优点

  • 控制实例的创建

    确保一个类只有一个实例,并提供一个全局访问点

  • 空间节约

    由于单例模式限制了实例的数量,因此可以减少由于创建多个相似实例而可能导致的内存浪费


缺点

  • 全局状态

    单例对象本质上是一个全局状态,这可能导致代码之间的不必要的耦合,使得单元测试变得困难

  • 对于并发环境可能需要特别处理

    在多线程环境下,需要特别小心以确保单例的线程安全


实现方式

使用一个变量存储类实例对象(值初始为 null/undefined

进行类实例化时,判断类实例对象是否存在,存在则返回该实例,不存在则创建类实例后返回

多次调用类生成实例方法,返回同一个实例对象

  1. 利用导出

    1
    export default new Func ()
  2. 惰性单例(使用时才new)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    /**
    * 单例模式类
    * 该类确保一个类只有一个实例,并且提供一个全局访问点来获得这个唯一实例。
    */
    class GenericSingletonPattern {
    // 私有静态成员变量,用于保存唯一实例
    static #instance;

    /**
    * 私有构造函数
    * 防止通过new关键字创建多个实例。
    */
    constructor() {
    if (GenericSingletonPattern.#instance) {
    throw new Error("Cannot instantiate singleton class using new operator.");
    }
    }

    /**
    * 公有静态方法,用于获取唯一实例
    * 如果实例不存在,则创建一个新的实例并返回;如果已存在,则直接返回该实例。
    * @returns {GenericSingletonPattern} 单例模式的唯一实例。
    */
    static getInstance() {
    if (!GenericSingletonPattern.#instance) {
    GenericSingletonPattern.#instance = new GenericSingletonPattern();
    }
    return GenericSingletonPattern.#instance;
    }

    }


    export default GenericSingletonPattern

    // region HOW TO USE
    // 获取单例对象的实例
    const instance1 = GenericSingletonPattern.getInstance();
    const instance2 = GenericSingletonPattern.getInstance();

    // 检查是否是同一个实例
    console.log(instance1 === instance2); // 输出: true

    // 试图使用 new 关键字创建实例,会抛出错误
    const instance3 = new GenericSingletonPattern(); // 抛出错误: Cannot instantiate singleton class using new operator.
    // endregion HOW TO USE


    这段代码定义了一个名为 GenericSingletonPattern 的类,它实现了单例模式。单例模式确保一个类只有一个实例,并提供一个全局访问点来获取这个唯一实例

    • 类中的 #instance 是一个私有的静态成员变量,用于保存唯一实例
    • 构造函数 constructor() 是私有的,它会在实例化时被调用。如果已经存在实例,则会抛出一个错误,防止通过 new 关键字创建多个实例
    • getInstance() 方法是一个公有的静态方法,用于获取唯一实例。如果实例不存在,则会创建一个新的实例并返回;如果已存在,则直接返回该实例


场景

  1. 定义命名空间和实现分支型方法
  2. 登录框
  3. vuex 和 redux中的store


源代码