📜  Python设计模式-原型(1)

📅  最后修改于: 2023-12-03 14:46:47.613000             🧑  作者: Mango

Python设计模式-原型

什么是原型模式?

原型模式是一种用于创建对象的设计模式,其中一个原型实例成为创建新对象的“蓝本”。该实例被克隆以生成新对象。这种类型的设计模式属于创建型模式,因为这种模式提供了一种不同于直接实例化对象的方法。

为什么使用原型模式?

在有些情况下,创建一个新对象的成本很高,因此可以通过克隆来更有效地创建一个新对象。原型设计模式提供了一种简便的方法来创建复杂对象。

实现原型模式的方式

要实现原型设计模式,需要满足以下要求:

  1. 具体原型类需实现克隆方法;
  2. new() 方法不能被使用。

在 Python 中,我们可以通过实现 clone() 方法来实现原型模式。

import copy

class Prototype:
    def __init__(self):
        self._objects = {}
    
    def register_object(self, name, obj):
        self._objects[name] = obj
    
    def unregister_object(self, name):
        del self._objects[name]
    
    def clone(self, name, **kwargs):
        obj = copy.deepcopy(self._objects.get(name))
        obj.__dict__.update(kwargs)
        return obj

上面代码中,Prototype 类维护了一组原型实例,它提供了注册和注销原型实例的方法。通过调用 clone 方法并传递原型实例名称和任意关键字参数(如果有)来创建新实例。

示例

下面是一个使用原始模式的示例,假设有一个图形类库,图形对象的创建成本较高。

import abc

class Graphic(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def draw(self):
        pass
    
    @abc.abstractmethod
    def clone(self):
        pass
    
class Rectangle(Graphic):
    def __init__(self, width, height):
        self._width = width
        self._height = height
    
    def draw(self):
        print(f'Drawing a rectangle ({self._width}, {self._height}).')
    
    def clone(self):
        return type(self)(self._width, self._height)
    
    
class Circle(Graphic):
    def __init__(self, radius):
        self._radius = radius
    
    def draw(self):
        print(f'Drawing a circle ({self._radius}).')
    
    def clone(self):
        return type(self)(self._radius)

通过上面的代码,我们定义了 Graphic 抽象基类和两个具体类,CircleRectangle。它们都继承了 Graphic,并实现了 drawclone 方法。

我们使用以下样例代码来测试上述代码:

PROTOTYPE_REGISTRY = {
    'Rectangle': Rectangle(3, 5),
    'Circle': Circle(10)
}

def main():
    prototypes = PROTOTYPE_REGISTRY
    
    rectangle = prototypes['Rectangle'].clone()
    rectangle.draw()
    
    circle = prototypes['Circle'].clone()
    circle.draw()

if __name__ == '__main__':
    main()

在上面的代码中,我们首先定义了一个 PROTOTYPE_REGISTRY 字典,它包含原型的实例,然后我们使用这些原型生成新的 RectangleCircle 实例,并调用它们的 draw 方法。

程序将输出以下内容:

Drawing a rectangle (3, 5).
Drawing a circle (10).
总结

原型设计模式提供了一个创建对象的简单方法,可以避免直接创建成本较高的对象。Python 中我们可以使用 deepcopy 方式来实现原型设计模式。