1. 介绍
单例模式的核心是确保一个类只有一个实例,并提供全局访问点。
设计要素 | 作用说明 |
---|---|
私有构造函数 | 禁止外部使用 new 创建实例 (private constructor() {}) |
静态私有属性 | 在类内部存储唯一实例 (private static instance: Singleton;) |
静态访问方法 | 提供全局访问入口 (public static getInstance()) |
延迟初始化 | 首次调用时才创建实例(节约资源) |
类型安全 | TS 类型系统确保实例访问安全 |
线程安全 | 在 JS/TS 单线程环境中天然安全(多线程环境需额外处理) |
核心遵循的原则
- 单一职责原则 (SRP)
单例模式确保一个类只负责管理自己的唯一实例创建和访问,职责单一明确。 - 开闭原则 (OCP)
通过私有构造函数和静态方法的设计,单例类对修改关闭(不能随意创建多个实例),但可以通过继承或扩展功能对扩展开放。 - 依赖倒置原则 (DIP)
客户端代码依赖于单例类提供的抽象接口,而不是具体的实例化细节。
2. 实现
2.1 经典实现(静态属性 + 私有构造)
// 经典实现(静态属性 + 私有构造)
export class Singleton {
// 1. 静态属性保存唯一实例
private static instance: Singleton;
// 2. 私有构造函数,防止外部实例化
private constructor() {}
// 3. 全局访问点
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
// 示例方法
public log(message:string):void {
console.log(`[Singleton] ${message}`)
}
}
// 使用
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true
instance1.log("Hello Singleton"); // [Singleton] Hello Singleton
2.2 懒汉式
class EagerSingleton {
// 类加载时立即创建实例
private static readonly instance: EagerSingleton = new EagerSingleton();
// 私有构造函数,防止外部实例化
private constructor() {}
// 全局访问点
public static getInstance(): EagerSingleton {
return this.instance;
}
}
// 使用
const eagerInstance1 = EagerSingleton.getInstance();
const eagerInstance2 = EagerSingleton.getInstance();
console.log(eagerInstance1 === eagerInstance2); // true
console.log("Hello EagerSingleton"); // [EagerSingleton] Hello EagerSingleton
2.3 使用命名空间(非类实现)
namespace SingletonNamespace {
// 私有实例
let instance: any;
// 通过函数暴露实例
export function getInstance<T>(c: {new(): T}): T {
if (!instance) {
instance = new c();
}
return instance;
}
}
class MyService {
constructor() {
console.log("MyService constructor");
}
}
// 使用
const service1 = SingletonNamespace.getInstance(MyService);
const service2 = SingletonNamespace.getInstance(MyService);
console.log(service1 === service2); // true
© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END
暂无评论内容