单例模式(Singleton Pattern)
🎯 单例模式(Singleton Pattern)
🧠 一句话定义:
单例模式保证一个类只有一个实例,并提供一个全局访问点。
🚪生活类比:
想象你操作的是一个「大门控制系统」,你不希望出现多个大门管理器,
否则:
- 一边开门
- 一边关门
可能就乱了!
✅ 单例 = 系统中只存在一个“大门控制器”实例
✅ 为什么需要单例模式?
问题 | 单例的作用 |
---|---|
全局只有一个对象 | 配置中心 / 日志管理器 / 线程池 等 |
控制资源竞争 | 避免创建多个实例带来的冲突 |
节省资源 | 重复创建开销大,浪费内存 |
方便统一管理 | 改配置只改一个地方,全局生效 |
✅ 优点 vs ❌ 缺点
优点 | 缺点 |
---|---|
全局唯一实例,易管理 | 不易扩展、违反开闭原则 |
避免资源重复创建 | 多线程需处理并发问题 |
提供全局访问点 | 容易滥用,隐藏依赖关系 |
🐍 Python 实现单例(完整代码)
✅ 方法一:经典方式(使用 __new__
)
class Singleton:_instance = Nonedef __new__(cls):if cls._instance is None:cls._instance = super(Singleton, cls).__new__(cls)return cls._instancedef __init__(self):self.value = 42
使用示例
a = Singleton()
b = Singleton()print(a is b) # True,说明 a 和 b 是同一个对象
b.value = 100
print(a.value) # 100,说明值同步变化
✅ 方法二:装饰器方式(推荐简洁)
# 单例装饰器定义
def singleton(cls):"""一个类装饰器,用于将目标类包装为单例类。多次实例化时始终返回同一个实例。"""instances = {} # 用于保存所有装饰过的类的实例def wrapper(*args, **kwargs):if cls not in instances:# 如果该类未被实例化过,则创建实例并缓存instances[cls] = cls(*args, **kwargs)return instances[cls]return wrapper
🧱 使用装饰器的类示例(配置管理器)
@singleton
class ConfigManager:def __init__(self):print("正在初始化配置...")self.config = {"host": "localhost","port": 8080}def set(self, key, value):self.config[key] = valuedef get(self, key):return self.config.get(key, None)
🧭 流程图(Mermaid)
或者类图表达:
📌 实际应用场景
场景 | 说明 |
---|---|
日志记录器 | 全局只需一个 log 实例 |
数据库连接池 | 管理连接的唯一实例 |
配置中心 | 全局统一管理配置项 |
控制器、服务类 | 比如任务调度器、缓存管理器等 |
🧠 总结口诀
✅ 单例模式:一生只创建一次,全局都用它。
用于「全局唯一资源访问 + 状态同步管理」
如果你想了解:
- 如何写线程安全的单例
- 如何实现懒汉式 vs 饿汉式单例(Java常见问题)
- 如何避免单例污染全局结构
我可以帮你扩展更多实战场景。要继续深入吗?🚀