站内链接:

介绍

介绍

单例模式是一种简单的设计模式, 用于确保某一个类在项目运行时仅仅存在一个实例对象, 并且自行实例化并向整个系统提供服务.

使用场景

  • 提供一个全局的访问,且只要求一个实例,如应用的配置信息
  • 创建一个对象比较耗费资源,如数据库连接管理、文件管理、日志管理等
  • 资源共享,如线程池
  • 工具类对象(也可以直接使用静态常量或者静态方法)
  • 要求一个类只能产生两三个实例对象,比如某些场景下,会要求两个版本的网络库实例,如公司内网和外网的网络库实例

要求:

  • 延时加载或者懒加载
  • 线程安全
  • 防止反射破坏

模式以及实现

  • 饿汉模式: 在类初始化时, 执行静态代码以及初始化静态域来完成实例的创建, 例如 python 的模块导入, 由 JVM/Python 虚拟机来确保线程安全
  • 懒汉模式: 在调用 getInstance()时才会去实例化类, 但是并非线程安全
  • 懒汉模式-线程安全: 在实例化时, 增加同步锁机制
  • 反射破坏: 利用反射机制去访问单例类的私有构造方法来进行实例化

装饰器在 python 中的实现

  • 使用模块, 一个模块本身就是一个单例(基于解释器)
  • __new__控制类的初始化
  • metaclass 元类来控制类的创建: 拦截类, 修改类定义, 返回类
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
# 使用__new__来实现单例
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance

# 使用wraps来装饰某一个类
from functools import wraps
def singleton(cls):
instances = {}
@wraps(cls)
def getinstance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances
return getinstance

@singleton
class A(object):
a = 1

# metaclass控制类的创建
class Singleton(object):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in _instances:
_instances[cls] = cls(*args, **kwargs)
return _instances[cls]

class B(object):
__metaclass__ = Singleton