建立型模式分为如下几种。python
以上 5 种建立型模式,除了工厂方法模式属于类建立型模式,其余的所有属于对象建立型模式。数据库
单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行建立这个实例的一种模式。设计模式
例如,Windows 中只能打开一个任务管理器,这样能够避免因打开多个任务管理器窗口而形成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。缓存
在计算机系统中,还有 Windows 的回收站、操做系统中的文件系统、多线程中的线程池、显卡的驱动程序对象、打印机的后台处理服务、应用程序的日志对象、数据库的链接池、网站的计数器、Web 应用的配置对象、应用程序中的对话框、系统中的缓存等经常被设计成单例。安全
单例模式有 3 个特色:网络
单例模式是设计模式中最简单的模式之一。一般,普通类的构造函数是公有的,外部类能够经过“new 构造函数()”来生成多个实例。多线程
可是,若是将类的构造函数设为私有的,外部类就没法调用该构造函数,也就没法生成多个实例。ide
这时该类自身必须定义一个静态私有实例,并向外提供一个静态的公有函数用于建立或获取该静态私有实例。函数
Singleton 模式一般有两种实现形式。性能
该模式的特色是类加载时没有生成单例,只有当第一次调用 get_instance 方法时才去建立这个单例。
class LazySingleton(object): __instance = None def __init__(self): """ Virtually private constructor. """ pass @staticmethod def get_instance(): """ Static access method. """ if LazySingleton.__instance == None: LazySingleton.__instance = LazySingleton() return LazySingleton.__instance s1 = LazySingleton() s2 = LazySingleton() print(s1._LazySingleton__instance, s2._LazySingleton__instance, end='\n') # 未调用get_instance方法时未建立 print(s1.get_instance(), s2.get_instance(), end='\n') # 指向同一对象
None None <__main__.LazySingleton object at 0x0000020A56899FD0> <__main__.LazySingleton object at 0x0000020A56899FD0>
注意:若是编写的是多线程程序,注意存在线程非安全的问题。若是保证线程安全,那么每次访问时都要同步,会影响性能,且消耗更多的资源,这是懒汉式单例的缺点。
该模式的特色是类一旦加载就建立一个单例,保证在调用 get_instance 方法以前单例已经存在了。
class HungrySingleton(object): __instance = None def __new__(cls, *args, **kwargs): if cls.__instance == None: cls.__instance = super(HungrySingleton, cls).__new__(cls) return cls.__instance @staticmethod def get_instance(): return HungrySingleton.__instance h1 = HungrySingleton() h2 = HungrySingleton() print(h1._HungrySingleton__instance, h2._HungrySingleton__instance, end='\n') # 未调用get_instance方法时已经建立 print(h1.get_instance(), h2.get_instance(), end='\n') # 与上面一致
<__main__.HungrySingleton object at 0x0000020A568A1048> <__main__.HungrySingleton object at 0x0000020A568A1048> <__main__.HungrySingleton object at 0x0000020A568A1048> <__main__.HungrySingleton object at 0x0000020A568A1048>
饿汉式单例在类建立的同时就已经建立好一个静态的对象供系统使用,之后再也不改变,因此是线程安全的,能够直接用于多线程而不会出现问题。
【例1】用懒汉式单例模式模拟产生美国当今总统对象。
分析:在每一届任期内,美国的总统只有一人,因此本实例适合用单例模式实现,图所示是用懒汉式单例实现的结构图。
class President(object): __instance = None def __init__(self): print("产生一个新总统") @staticmethod def get_instance(): if President.__instance == None: President.__instance = President() else: print("已经有一个总统了") return President.__instance def get_name(self): print("特朗普是新总统") if __name__ == '__main__': p1 = President.get_instance() p1.get_name() p2 = President.get_instance() p2.get_name() if p1 == p2: print('他们是同一人') else: print('他们不是同一人')
产生一个新总统 特朗普是新总统 已经有一个总统了 特朗普是新总统 他们是同一人
前面分析了单例模式的结构与特色,如下是它一般适用的场景的特色。
单例模式可扩展为有限的多例(Multitcm)模式,这种模式可生成有限个实例并保存在 ArmyList 中,客户须要时可随机获取,其结构图如图所示。