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>
     
  • 相关阅读:
    Mybatis 延迟加载策略
    Mybatis中的多表查询 多对多
    Mybatis中的多表查询 多对一,一对多
    Mybatis 的动态 SQL 语句
    Mybatis中的连接池
    判断一个对象是否为数组
    包装对象概念 (做好事不留名的雷锋)
    javascript 继承之拷贝,原型,类式
    ajax参数
    面向对象小实例之 选项卡
  • 原文地址:https://www.cnblogs.com/zcok168/p/9248509.html
Copyright © 2011-2022 走看看