| name | metaframe-singleton-pattern |
|---|---|
| category | engineering |
| description | 单例模式 | Code & Engineering |
英文名: Singleton Pattern
分类: 编码实践
作者: Gamma, Helm, Johnson, Vlissides, 1994
复杂度: beginner
成熟度: foundational
AI 相关: ❌ 否
确保一个类只有一个实例,并提供一个访问它的全局入口点
- 单实例保证:进程中只能存在该类的一个对象;通过私有构造函数强制实现
- 全局访问点:静态 getInstance() 方法提供从代码库任何地方访问单一实例的知名入口
- 懒加载 vs 饿加载:实例可在首次访问时创建(懒加载)或在类加载时创建(饿加载),各有不同的线程安全含义
- 将构造函数设为私有:防止外部代码直接使用 new 关键字实例化类
- 声明私有静态实例字段:在类内部持有单一实例
- 提供公共静态访问方法:实现 getInstance(),在第一次调用时创建实例,后续每次调用返回该实例
- 处理线程安全:在多线程环境中,使用双重检查锁定、按需初始化持有者或语言级保证来防止竞态条件
- 考虑依赖注入作为替代方案:在现代应用中,优先通过 DI 容器注入单一共享实例,而非依赖静态访问器
['必须存在唯一一个共享资源——如线程池、配置注册表或硬件接口驱动', '需要全局协调,多个实例的代价会导致正确性问题(如重复缓存)', '遗留代码库无法使用依赖注入,需要一个受控的全局访问点']
- 优先使用 DI 容器管理的单例而非静态 getInstance(),以获得可测试性和生命周期控制
- 使用线程安全的初始化方式(Java 中的枚举单例、Python 中的模块级对象)以避免微妙的并发缺陷
- 将单例限制于无状态或只追加的资源;可变共享状态是并发风险
- 不要将单例用于领域对象——这使它们无法变化、无法隔离测试或并发运行
- 不要在单例中存储可变业务状态,因为这会引入竞态条件并使测试依赖于顺序
- 不要将单例用作方便的全局变量袋——它是一种随时间侵蚀可维护性的架构耦合
Sources: SDFrame (Software Design) MetaFrame: 💻 Code & Engineering / 编码与工程