参考了《人人都懂设计模式:从生活中领悟设计模式(Python实现)》
Ensure a class has only one instance, and provide a global point of access to it.
确保一个类只有一个实例,并且提供一个访问它的全局方法。
应用场景
- 你希望这个类有且只能有一个实例;
- 项目中的一些全局管理类。
实现方式(Python)
1) 重写__new__和__init__方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Singleton(object): __instance = None __is_first_init = True
def __new__(cls, name): """ __new__是一个类方法,用于创建对象,创建的对象会被传递给__init__方法里的self参数 """ if not cls.__instance: Singleton.__instance = super().__new__(cls) return cls.__instance
def __init__(self, name): """__init__是一个对象方法,用来初始化__new__创建的对象""" if self.__is_first_init: self.__name = name Singleton.__is_first_init = False
def get_name(self): return self.__name
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Singleton(type): """metaclass都要继承type""" def __init__(cls, what, bases=None, dict=None): """进行一些初始化的操作,如一些全局变量的初始化""" super().__init__(what, bases, dict) cls._instance = None
def __call__(cls, *args, **kwargs): """创建实例,在创建的过程中会调用class的__new__和__init__方法""" if cls._instance is None: cls._instance = super().__call__(*args, **kwargs) return cls._instance
class CustomClass(metaclass=Singleton): def __init__(self, name): self.__name = name
def get_name(self): return self.__name
|
3) 装饰器的方法
装饰器的实质就是对传送进来的参数进行补充,可以在不对原有的类做任何代码变动的情况下增加额外的功能,使用装饰器可以装饰多个类。用装饰器的方法实现单例模式,通用性非常高,在实际项目中用得非常多。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| def singleton_decorator(cls, *args, **kwargs): """定义单例装饰器""" instance = {}
def wrapper_singleton(*args, **kwargs): if cls not in instance: instance[cls] = cls(*args, **kwargs) return instance[cls]
return wrapper_singleton
@singleton_decorator class Singleton: """使用单例装饰器修饰一个类""" def __init__(self, name): self.__name = name
def get_name(self): return self.__name
|
实现方式(C++)
懒汉
第一次用到实例的时候才会去实例化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class singleton { private: singleton(); static singleton *p = nullptr; public: static singleton *instance(); };
singleton *singleton::instance() { if (p == nullptr) { p = new singleton(); } return p; }
|
饿汉
单例类定义的时候就进行实例化
1 2 3 4 5 6 7 8 9 10 11 12 13
| class singleton { private: singleton(); static singleton *p = new singleton(); public: static singleton *instance(); };
singleton *singleton::instance() { return p; }
|