设计模式,单例模式

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>
 
原文地址:https://www.cnblogs.com/zcok168/p/9248509.html