原型模式(Prototype Pattern)
以画布为例


In [2]:
class simpleLayer(object):
    background=[0,0,0,0]
    content="blank"
    def getContent(self):
        return self.content
    def getBackgroud(self):
        return self.background
    def paint(self,painting):
        self.content=painting
    def setParent(self,p):
        self.background[3]=p
    def fillBackground(self,back):
        self.background=back

在实际的实现中,图层实现会很复杂,这里仅介绍相关的设计模式,做了比较大的抽象,用background表示背景的RGBA,简单用content表示内容,除了直接绘画,还可以设置透明度。


In [4]:
dog_layer=simpleLayer()
dog_layer.paint('Dog')
dog_layer.fillBackground([0,0,255,0])
print('background:',dog_layer.getBackgroud())
print('Painting:', dog_layer.getContent())


background: [0, 0, 255, 0]
Painting: Dog

接下来,如果需要再生成一个同样的图层,再填充同样的颜色,再画一只同样狗,该如何做呢?还是按照新建图层、填充背景、画的顺序么?或许你已经发现了,这里可以用复制的方法来实现,而复制(clone)这个动作,就是原型模式的精髓了。 按照此思路,在图层类中新加入两个方法:clone和deep_clone


In [6]:
from copy import copy, deepcopy
class simpleLayer(object):
    background=[0,0,0,0]
    content="blank"
    def getContent(self):
        return self.content
    def getBackgroud(self):
        return self.background
    def paint(self,painting):
        self.content=painting
    def setParent(self,p):
        self.background[3]=p
    def fillBackground(self,back):
        self.background=back
    def clone(self):
        return copy(self)
    def deep_clone(self):
        return deepcopy(self)

In [7]:
dog_layer=simpleLayer()
dog_layer.paint('Dog')
dog_layer.fillBackground([0,0,255,0])
print('background:',dog_layer.getBackgroud())
print('Painting:', dog_layer.getContent())
another_dog_layer=dog_layer.clone()
print('background:',another_dog_layer.getBackgroud())
print('Painting:', another_dog_layer.getContent())


background: [0, 0, 255, 0]
Painting: Dog
background: [0, 0, 255, 0]
Painting: Dog

大多数编程语言中,都会涉及到深拷贝和浅拷贝的问题,一般来说,浅拷贝会拷贝对象内容及其内容的引用或者子对象的引用,但不会拷贝引用的内容和子对象本身;而深拷贝不仅拷贝了对象和内容的引用,也会拷贝引用的内容。所以,一般深拷贝比浅拷贝复制得更加完全,但也更占资源(包括时间和空间资源)。举个例子,下面的场景,可以说明深拷贝和浅拷贝的区别。

Advantages

  • 性能极佳
  • 简化对象创建、同时避免构造函数的约束

Usages

  1. 对象在修改过后,需要复制多份的场景。如本例和其它一些涉及到复制、粘贴的场景;
  2. 需要优化资源的情况。如,需要在内存中创建非常多的实例,可以通过原型模式来减少资源消耗。此时,原型模式与工厂模式配合起来,不管在逻辑上还是结构上,都会达到不错的效果;
  3. 某些重复性的复杂工作不需要多次进行。如对于一个设备的访问权限,多个对象不用各申请一遍权限,由一个设备申请后,通过原型模式将权限交给可信赖的对象,既可以提升效率,又可以节约资源。

Disadvantage

  • 深拷贝和浅拷贝的使用需要事先考虑周到
  • 某些编程语言中,拷贝会影响到静态变量和静态函数的使用

In [ ]: