96 lines
2.2 KiB
Markdown
96 lines
2.2 KiB
Markdown
# 单例模式
|
||
|
||
单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点。
|
||
|
||
## 应用场景
|
||
|
||
1. 数据库连接池
|
||
2. 配置管理器
|
||
3. 日志记录器
|
||
4. 线程池管理
|
||
5. 缓存管理
|
||
|
||
## 实现方式
|
||
|
||
在Python中实现单例模式有多种方式:
|
||
|
||
1. 使用`__new__`方法(基本实现):
|
||
|
||
```python
|
||
class Singleton:
|
||
_instance = None
|
||
|
||
def __new__(cls, *args, **kwargs):
|
||
if not cls._instance:
|
||
cls._instance = super().__new__(cls)
|
||
return cls._instance
|
||
```
|
||
|
||
2. 使用装饰器实现(更优雅的方式):
|
||
|
||
```python
|
||
def singleton(cls):
|
||
_instance = {}
|
||
def inner(*args, **kwargs):
|
||
if cls not in _instance:
|
||
_instance[cls] = cls(*args, **kwargs)
|
||
return _instance[cls]
|
||
return inner
|
||
|
||
@singleton
|
||
class Config:
|
||
def __init__(self):
|
||
self.config = {}
|
||
```
|
||
|
||
3. 使用元类实现(更高级的方式):
|
||
|
||
```python
|
||
class SingletonMeta(type):
|
||
_instances = {}
|
||
def __call__(cls, *args, **kwargs):
|
||
if cls not in cls._instances:
|
||
cls._instances[cls] = super().__call__(*args, **kwargs)
|
||
return cls._instances[cls]
|
||
|
||
class Database(metaclass=SingletonMeta):
|
||
def __init__(self):
|
||
self.connection = None
|
||
```
|
||
|
||
## 优点
|
||
|
||
1. 保证一个类只有一个实例,减少内存开销
|
||
2. 避免对资源的多重占用
|
||
3. 提供了对唯一实例的全局访问点
|
||
4. 实现了对实例创建的控制
|
||
|
||
## 缺点
|
||
|
||
1. 单例模式可能隐藏了类之间的依赖关系
|
||
2. 单例模式违反了单一职责原则
|
||
3. 在并发环境下需要特殊处理
|
||
4. 测试时可能会遇到困难
|
||
|
||
## 最佳实践
|
||
|
||
1. 优先考虑使用模块级别的变量(Python 模块天然是单例的)
|
||
2. 如果需要类级别的单例,推荐使用装饰器方式
|
||
3. 需要继承时,使用元类方式
|
||
4. 在多线程环境下,需要添加线程锁保证线程安全
|
||
|
||
```python
|
||
import threading
|
||
|
||
class ThreadSafeSingleton:
|
||
_instance = None
|
||
_lock = threading.Lock()
|
||
|
||
def __new__(cls):
|
||
if cls._instance is None:
|
||
with cls._lock:
|
||
if cls._instance is None:
|
||
cls._instance = super().__new__(cls)
|
||
return cls._instance
|
||
```
|