zoukankan      html  css  js  c++  java
  • 设计模式,单例模式

    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>
     
  • 相关阅读:
    [LeetCode 1029] Two City Scheduling
    POJ 2342 Anniversary party (树形DP入门)
    Nowcoder 106 C.Professional Manager(统计并查集的个数)
    2018 GDCPC 省赛总结
    CF 977 F. Consecutive Subsequence
    Uva 12325 Zombie's Treasure Chest (贪心,分类讨论)
    Poj 2337 Catenyms(有向图DFS求欧拉通路)
    POJ 1236 Network of Schools (强连通分量缩点求度数)
    POJ 1144 Network (求割点)
    POJ 3310 Caterpillar(图的度的判定)
  • 原文地址:https://www.cnblogs.com/zcok168/p/9248509.html
Copyright © 2011-2022 走看看