Python与设计模式:创建型模式(下)

2. 建造者模式

建造者模式主要用于协调对象创建过程中的多个步骤。常用的例子是生产不同配置的电脑,根据用户传入的不同配置参数,返回搭配不同硬件的电脑。

一般来说,通过控制实例的初始化过程,即__init__()函数,就可以实现建造者模式,大家平时也经常使用,用伪代码举例如下:


    class 万能培训机构:
      def __init__(self, 学历, 工作经验, 项目经验):
        self.学历 = 学历印刷厂(学历)
        self.工作经验 = 工作经验加速器(工作经验)
        self.项目经验 = 项目经验生成器(项目经验)


3. 原型模式

原型模式无非是对象复制,在Python中,引入 copy.deepcopy() 方法可能是最简单的。

比如说,我们实现一个clone()方法,就可以以任意实例为原型创建新对象了:


    from copy import deepcopy

    class A:
      def clone(self):
        obj = deepcopy(self)
        return obj

    a = A()
    b = a.clone()

原型模式在实践中还算常见,比如采购过程中,有时会有定期订单,为避免每次都重新填写繁琐的订单信息,就会提供复制订单的便捷操作,代码就可以直接使用这个模式。当然,事实上我们写代码的时候,可能并不记得这就叫原型模式。

这边需要注意的问题主要是深复制与浅复制的区别。浅复制时,如果原对象中引用了其它对象,则新对象也会尽量使用这个引用;而深复制时,则会层层递归,创建新对象。


4. 单例模式

单例模式仅允许创建一个实例,那么,就要解决怎么判断是否已创建实例,怎么找到这个实例的问题。

在Python中,我们可以通过类字典来保存这个实例:


    class Fullstack():
       _programmer = None
       def __new__(cls, *args, **kwargs):
          if cls._programmer is None:
            cls._programmer = super().__new__(cls, *args, **kwargs)
          return cls._programmer

也可以在某个函数的命名空间中保存这个实例,比如使用装饰器:


    def singleton(cls):
      _instance = {}
      @wraps(cls)
      def inner():
        if cls not in _instance:
          _instance[cls] = cls()
        return _instance[cls]
      return inner

    @singleton
    class Fullstack: pass

    fullstack = Fullstack()

当然,有时也作为全局变量,保存在某个模块的命名空间中:


    PROGRAMMER = None

    def only_you():
      if PROGRAMMER is None:
        PROGRAMMER = Fullstack()
      return PROGRAMMER

    fullstack = only_you()

在实际应用中,很有可能要处理多线程的问题。要实现单例模式的线程安全,可以直接引入线程锁,比如说:


    import threading

    _lock = threading.Lock()
    with _lock:
      pass # return or create the instance

当然,真正的工程实践可能要比想象的还要复杂。

比如分布式场景下的定时任务问题,光凭代码中的线程安全的单例模式,依然不能解决多个应用同时开启任务的问题,这时就必须依赖外部的锁机制,比如文件锁或redis锁等进行控制——当然,这种情况下,单例模式还是不是最好的方案,是值得讨论的。


公众号:ReadingPython


发表评论

评论列表,共 0 条评论