【设计模式】单例模式

参考了《人人都懂设计模式:从生活中领悟设计模式(Python实现)》

Ensure a class has only one instance, and provide a global point of access to it.
确保一个类只有一个实例,并且提供一个访问它的全局方法。

应用场景

  1. 你希望这个类有且只能有一个实例;
  2. 项目中的一些全局管理类。

    实现方式(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):
# 在这里定义的变量相当于C++类中定义的static变量,相当于类里的全局变量
# Python中的前双下划线表示C++中的private成员,前单下划线表示protected成员
__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

2) 自定义metaclass的方法

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;
}