Javascript设计模式 - 《单例模式(创建型)》
概念
单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例
单例模式通过将类的构造函数设为私有,防止外部直接创建实例,同时提供一个静态方法或者属性来获取该实例,从而保证在整个应用程序中只有一个实例存在
单例模式的核心思想是确保一个类只有一个实例存在,并提供一个全局访问点来访问该实例
这种模式的优点在于,可以节省系统资源,提高系统性能,同时也可以保证全局访问点的一致性
然而,需要注意的是,单例模式可能会引入全局状态,增加了代码的耦合度,降低了代码的可测试性
因此,在使用单例模式时需要谨慎考虑
举个简单的例子,考虑一个日志记录器
无论在应用程序的任何地方都需要记录日志,而且只需要一个日志记录器实例来处理所有的日志记录任务
使用单例模式,可以确保在整个应用程序中只有一个日志记录器实例存在,从而实现日志记录的统一管理和控制
实现条件
- 单例类的构造函数必须是私有的,这样才能将类的创建权控制在类的内部,从而使得类的外部不能创建类的实例。
- 单例类通过一个私有的静态变量来存储其唯一实例。
- 单例类通过提供一个公开的静态方法,使得外部使用者可以访问类的唯一实例
注意:
因为单例类的构造函数是私有的,所以单例类不能被继承
优点
控制实例的创建
确保一个类只有一个实例,并提供一个全局访问点
空间节约
由于单例模式限制了实例的数量,因此可以减少由于创建多个相似实例而可能导致的内存浪费
缺点
全局状态
单例对象本质上是一个全局状态,这可能导致代码之间的不必要的耦合,使得单元测试变得困难
对于并发环境可能需要特别处理
在多线程环境下,需要特别小心以确保单例的线程安全
实现方式
使用一个变量存储类实例对象(值初始为 null/undefined
)
进行类实例化时,判断类实例对象是否存在,存在则返回该实例,不存在则创建类实例后返回
多次调用类生成实例方法,返回同一个实例对象
利用导出
1
export default new Func ()
惰性单例(使用时才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()
方法是一个公有的静态方法,用于获取唯一实例。如果实例不存在,则会创建一个新的实例并返回;如果已存在,则直接返回该实例
- 类中的
场景
- 定义命名空间和实现分支型方法
- 登录框
- vuex 和 redux中的store