• 设计模式之创建模式


    1. 单例模式:

      a. 使用import

    #a.py
    
    class Animal(object):
        def __init__(self,name,coler):
            self.name = name
            self.coler = coler
        def run(self):
            print('{} {} can run!'.format(self.coler,self.name))
            
    animal = Animal('dog','white')
    # b.py
    
    from a import animal
    
    animal.run()

      python中的模块是天然的单例  

      b.使用装饰器

    def Singleton(cls):
        _instance = {}
    
        def wrapper(*args, **kwargs):
            if cls not in _instance:
                _instance[cls] = cls(*args, **kwargs)
            return _instance[cls]
    
        return wrapper
    
    
    @Singleton
    class A(object):
        def __init__(self, a):
            self.a = a
    
    
    a = A('sss')
    print(id(a))
    print a.a
    b = A('fffff')
    print b.a
    
    
    # output:
        44971888
        sss
        44971888
        sss

      上面装饰器的方法实现了单例,当A被第一次实例化为a时,self.a = 'sss', 下次b = A('fffff')时,装饰器判定A类已经有了实例,就会直接返回实例a,此时b=a,并未进行实例化,而是引用赋值,所以a,b的实例和self.a是一样的

      c. 重写__new__方法

    import threading
    
    class B(object):
        lock = threading.Lock()    # 为了防止多线程造成多个实例,需要用到线程锁
        _instance = None
    
        def __init__(self):
            self.b = {}
    
        def __new__(cls, *args, **kwargs):
            if not B._instance:    # 如果类没有实例
                with B.lock:    # 线程加锁
                    if not B._instance:  # 再次判断是否有实例(可能其他线程抢先创建了实例)
                        B._instance = object.__new__(cls)  # 创建实例
            return B._instance    # 如果已经有实例,直接返回实例
    
        def push(self):
            self.b = {'1': 1}
    
    
    b1 = B()
    print(id(b1))
    b1.push()
    print b1.b
    b2 = B()
    print id(b2)
    print b2.b
    
    
    # output:
        44409392
        {'1': 1}
        44409392
        {} 

       这个方法有个问题,实例b1执行push方法后,slef.b = {'1':1}

       但是b2实例化后self.b = {}, 明白了吗? __init__被再次执行了

     

      d.元类实现

    class SingletonType(type):
        def __init__(self, *args, **kwargs):
            super(SingletonType, self).__init__(*args, **kwargs)
    
        def __call__(cls, *args, **kwargs):  # 这里的cls,即Foo类
            print('cls', cls)
            obj = cls.__new__(cls, *args, **kwargs)
            cls.__init__(obj, *args, **kwargs)  # Foo.__init__(obj)
            return obj
    
    
    metaclass = SingletonType
    
    
    class Foo():  # 指定创建Foo的type为SingletonType
        def __init__(self, name):
            self.name = name
    
        def __new__(cls, *args, **kwargs):
            return object.__new__(cls)
    
    
    obj1 = Foo('xx')
    print(id(obj1))
    print(obj1.name)
    obj2 = Foo('xxx')
    print(id(obj2))
    print(obj2.name)
    
    # output:
        43996104
        xx
        43996144
        xxx

    2. 抽象工厂模式

      

    # -*- coding:utf-8 -*-
    
    import abc
    import six
    
    
    class Phone(object):
        def installer_cpu(self):
            pass
    
    
    class Notebook(object):
        def installer_cpu(self):
            pass
    
    
    class XiaomiPhone(Phone):
        def installer_cpu(self):
            print('骁龙855')
    
    
    class HuaweiPhone(Phone):
        def installer_cpu(self):
            print('麒麟980')
    
    
    class XiaomiNotebook(Notebook):
        def installer_cpu(self):
            print('intel i7-8550u')
    
    
    class HuaweiNotebook(Notebook):
        def installer_cpu(self):
            print('intel i5-8265u')
    
    
    @six.add_metaclass(abc.ABCMeta)
    class Factory(object):
        """
        抽象工厂类
        """
    
        @abc.abstractmethod
        def production_phone(self):
            pass
    
        @abc.abstractmethod
        def production_notebook(self):
            pass
    
    
    class XiaomiFactory(Factory):
        """
        小米的生产工厂
    
        """
    
        def production_phone(self):
            return XiaomiPhone()
    
        def production_notebook(self):
            return XiaomiNotebook()
    
    
    class HuaweiFactory(Factory):
        """
        华为的生产工厂
    
        """
    
        def production_phone(self):
            return HuaweiPhone()
    
        def production_notebook(self):
            return HuaweiNotebook()
    
    
    def main():
        # 要一个华为手机
        Huawei = HuaweiFactory()
        huawei_p30 = Huawei.production_phone()
        huawei_p30.installer_cpu()
    
        # 要一个小米手机
        Xiaomi = XiaomiFactory()
        xiaomi9 = Xiaomi.production_phone()
        xiaomi9.installer_cpu()
    
        # 要一个huawei笔记本
        Huawei = HuaweiFactory()
        huawei_matebook14 = Huawei.production_notebook()
        huawei_matebook14.installer_cpu()
    
        # 要一个小米的笔记本
        Xiaomi = XiaomiFactory()
        xiaomi_bookPro = Xiaomi.production_notebook()
        xiaomi_bookPro.installer_cpu()
    
    
    if __name__ == '__main__':
        main()

    # output:

      麒麟980
      骁龙855
      intel i5-8265u
      intel i7-8550u

     
  • 相关阅读:
    47c# 新建线程Thread,线程内与操作窗体控件
    48Command line is too long. Shorten command line for Test or also for
    MySQL 基础
    MySQL 的 GRANT和REVOKE 命令
    Linux 配置免密登录
    本地多个rdb文件,导入自建redis
    自建codis上阿里云
    Windows删除指定目录下的3天前的文件
    VS2017:提示“Error MSB8020 The build tools for v142 (Platform Toolset = 'v142') cannot be found. 。。。。”错误解决办法
    根据文件File,返回名称excel名称管理器对应的行和列
  • 原文地址:https://www.cnblogs.com/wangbaojun/p/11304010.html
Copyright © 2020-2023  润新知