单例设计模式
1、机制
确保类只有一个特定类型的对象,并提供全局访问点。
单例模式通常用于下列情形:日志记录或数据库操作、打印机后台处理程序,以及其他程序——该程序运行过程中只能生成一个实例,以避免对同一资源产生相互冲突的请求。例如:希望使用一个数据库对象对数据库进行操作,以保持数据的一致性,或者使用一个日志类的对象,将多项服务的日志信息按照顺序转储到一个特定的日志文件中。
简言之,单例设计模式的意图如下所示:
*、确保类有且只有一个对象被创建
*、为对象提供一个访问点,以使程序可以全局访问该对象
*、控制共享资源的并行访问
利用Python实现经典的单例模式
class Singleton(object): def __new__(cls): if not hasattr(cls, 'instance'): cls.instance = super(Singleton,cls).__new__(cls) return cls.instance if __name__ == '__main__': s = Singleton() print('object created', s) s1 = Singleton() print('object created', s1)
在上面的代码中,通过覆盖__new__方法(用于实例化的特殊方法)来控制对象的创建,对象s就是由该方法所创建的,但在创建之前,该方法会检查对象是否存在;
方法hasattr用于查看对象cls是否具有属性instance,该属性的作用是检查该类是否已经生成了一个对象,当对象s1被请求的时候,hasattr()发现对象已经存在,so,对象s1将被分配已有的对象实例。
2、单例模式的懒汉式实例化
单例模式的用例之一就是懒汉式实例化。例如:在导入模块的时候,我们可能会无意中创建一个对象,但当时用不到它。懒汉式实例化能够确保在实际需要时才创建对象。
class Singleton(object): __instance = None def __init__(self): if not Singleton.__instance: print("__init__ method called..") else: print("instance already created:", self.getInstance()) @classmethod def getInstance(cls): if not cls.__instance: cls.__instance = Singleton() return cls.__instance if __name__ == '__main__': s = Singleton() # class 初始化,但object没有创建 print('object created', Singleton.getInstance()) # object在这创建 s1 = Singleton() # instance already created print('object created', s1)
3、单例模式的缺点
由于单例具有全局访问权限,因此会出现一些缺陷:
1.全局变量可能在某处已经被误改,但是开发人员仍然认为它们没有发生变化,而该变量还在应用程序的其它位置被使用。
2.可能会对同一对象创建多个引用。由于单例只创建一个对象,因此会对同一个对象创建多个引用。
3.所有依赖于全局变量的类都会由于一个类的改变而紧密耦合为全局数据,从而可能在无意中影响另一个类。