设计模式之创建模式

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

 

猜你喜欢

转载自www.cnblogs.com/wangbaojun/p/11304010.html