GOF设计模式:
创建型 1. Factory Method(工厂方法) 2. Abstract Factory(抽象工厂) 3. Builder(建造者) 4. Prototype(原型) 5. Singleton(单例) 结构型 6. Adapter Class/Object(适配器) 7. Bridge(桥接) 8. Composite(组合) 9. Decorator(装饰) 10. Facade(外观) 11. Flyweight(享元) 12. Proxy(代理) 行为型 13. Interpreter(解释器) 14. Template Method(模板方法) 15. Chain of Responsibility(责任链) 16. Command(命令) 17. Iterator(迭代器) 18. Mediator(中介者) 19. Memento(备忘录) 20. Observer(观察者) 21. State(状态) 22. Strategy(策略) 23. Visitor(访问者)
单例模式:一个类无论你实例化多少次,他的对象始终都是一个内存地址。
比如,某个服务器程序的配置信息存放在一个文件中,客户端通过一个 AppConfig 的类来读取配置文件的信息。如果在程序运行期间,有很多地方都需要使用配置文件的内容,也就是说,很多地方都需要创建 AppConfig 对象的实例,这就导致系统中存在多个 AppConfig 的实例对象,而这样会严重浪费内存资源,尤其是在配置文件内容很多的情况下。事实上,类似 AppConfig 这样的类,我们希望在程序运行期间只存在一个实例对象。
实现单例模式的几种方式:
1.使用模块:
class Singleton(object): def foo(self): pass singleton = Singleton()
将上面的代码保存在文件mysingle.py中,然后这样使用:
from mysingle import sinleton
singleton.foo()
直接在其他文件中导入此文件中的对象,这个对象即是单例模式的对象
2.基于__new__方法实现(推荐使用,方便):
class Singleton(): def __new__(cls): # 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象 if not hasattr(cls, 'instance'):#hasattr()内置函数判断对象是否包含对应属性 cls.instance = super().__new__(cls)#super()在子类中调用父类方法解决多重继承问题 return cls.instance obj1 = Singleton() obj2 = Singleton() obj1.attr1 = 'value1' print (obj1.attr1, obj2.attr1) print (obj1 is obj2) # 输出结果: # value1,value1 # True
#为了保证线程安全需要在内部加入锁,采用这种方式的单例模式,以后实例化对象时,和平时实例化对象的方法一样 obj = Singleton() import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): pass #实例化一个对象时,是先执行了类的__new__方法(没写时,默认调用object.__new__),实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,基于这个,实现单例模式 def __new__(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = object.__new__(cls) return Singleton._instance obj1 = Singleton() obj2 = Singleton() print(obj1,obj2) def task(arg): obj = Singleton() print(obj) for i in range(10): t = threading.Thread(target=task,args=[i,]) t.start() # <__main__.Singleton object at 0x00000187467F0240> <__main__.Singleton object at 0x00000187467F0240> # <__main__.Singleton object at 0x00000187467F0240> # <__main__.Singleton object at 0x00000187467F0240> # <__main__.Singleton object at 0x00000187467F0240> # <__main__.Singleton object at 0x00000187467F0240> # <__main__.Singleton object at 0x00000187467F0240> # <__main__.Singleton object at 0x00000187467F0240> # <__main__.Singleton object at 0x00000187467F0240> # <__main__.Singleton object at 0x00000187467F0240> # <__main__.Singleton object at 0x00000187467F0240> # <__main__.Singleton object at 0x00000187467F0240>
3.使用装饰器:
def singleton(cls): instances = {} def getinstance(*args,**kwargs): if cls not in instances: # 该函数会判断某个类是否在字典 instances 中,如果在,会将 cls 作为 key,cls(*args, **kwargs) 作为 value 存到 instances 中, # 否则,直接返回 instances[cls] instances[cls] = cls(*args,**kwargs) return instances[cls] return getinstance @singleton# 定义了一个装饰器 singleton,它返回了一个内部函数 getinstance class MyClass: a = 1 c1 = MyClass() c2 = MyClass() print(c1,c2) print(c1 == c2) # <__main__.MyClass object at 0x0000019109E89A20>,<__main__.MyClass object at 0x0000019109E89A20> # True
4.基于metaclass(元类)方式实现:
元类可以控制类的创建过程,它主要做三件事:
- 拦截类的创建
- 修改类的定义
- 返回修改后的类
import threading class SingletonType(type): _instance_lock = threading.Lock() def __call__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): with SingletonType._instance_lock: if not hasattr(cls, "_instance"): cls._instance = super().__call__(*args, **kwargs) return cls._instance class Foo(metaclass=SingletonType): def __init__(self,name): self.name = name obj1 = Foo('name') obj2 = Foo('name') print(obj1,obj2) # <__main__.Foo object at 0x000001B1F5B59B00>,<__main__.Foo object at 0x000001B1F5B59B00>