python设计模式(一)之单例模式
初闻设计模式这个词汇,对于我来说其实是一头雾水的,看了一些相关书籍还是觉得有些云里雾里的,于是就想写几篇关于基本设计模式的博客,我会从 1.类别,2.定义,3.应用场景,4.代码实现,5.优缺点,这五个方面给自己理清一下思路,如有不对之处,还望多多指正。
设计模式类别分为三大类:
一、创建型:提供实例化的方法,为适合的状况提供相应的对象创建方法。
二、结构型:通常用来处理实体之间的关系,使得这些实体能够更好地协同工作。
三、行为型:用于在不同的实体进行通信,为实体间的通信提供更容易,更灵活的通信方法。
首先先来看一下单例模式。
定义:保证一个类只有一个实例,并提供一个访问它的全局访问点。
类别:单例模式是实例化方法,是一种创建型的设计模式。
应用场景:有些对象我们只需要一个,如线程池,缓存,网站计数器,如果实例化很多这样的对象,无疑浪费了很多系统资源,也会使缓存没有了意义。这时,我们需要一个特殊的类,每次实例化这个类都只有一个这样的实例,单例模式就为我们提供了这样的方法。
代码实现:
实现方式1:通过模块导入的方式。
# singleton.py class Singleton1(object): def __init__(self,name): self.name = name sing = Singleton1('jack')
# test.py from sing.singleton import sing a = sing b = sing a.name = 'rose' b.name = 'mike' print(id(a),id(b)) # ==> 4421234192 4421234192 print(a.name) #==> mike
我们可以通过打印结果看到实例化出来的两个对象实际上是同一个对象。
实现方式2:使用装饰器
def Singleton(cls): _instance = {} def _singleton(*args, **kargs): if cls not in _instance: _instance[cls] = cls(*args, **kargs) return _instance[cls] return _singleton @Singleton class A(object): def __init__(self, x=0): self.x = x a1 = A(2) a2 = A(3)
装饰器都是闭包函数,每次实例化都会先检查这个类名是否在_instance字典中出现,如果没有出现,会将这个类加入到这个字典并且返回,如果出现过了,则会返回之前的实例化的类,参数也是第一次传入的参数,让我们看一下打印结果:
print(id(a1),id(a2)) # ==》4430388304 4430388304 print(a1.x,a2.x) # ==》 2 2
实现方式3:通过类创建
class Singleton(object): __instance = None def __new__(cls, *args, **kwargs): if cls.__instance is None: cls.__instance = super( Singleton, cls).__new__(cls) return cls.__instance def __init__(self, status_number): self.status_number = status_number
这里要注意self.__new__是优先于self.__init__方法的,每次实例化对象都会先执行__new__,返回了一个类的实例,再进行__init__初始化的。从这个new方法可以看出他返回的都是同一个类属性。
single1 = Single('jack') single2 = Single('mike') print(single1.name) # ==> mike print(id(single1),id(single2)) # ==> 4485909640 4485909640
优点:
一、节约了系统资源。由于系统中只存在一个实例对象,对与一些需要频繁创建和销毁对象的系统而言,单例模式无疑节约了系统资源和提高了系统的性能。
二、因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。
缺点:
一、由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
二、单例类的职责过重,在一定程度上违背了“单一职责原则”。