浅谈Python设计模式 -- 原型模式

原型模式:

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式本质就是克隆对象,所以在对象初始化操作比较复杂的情况下,很实用,能大大降低耗时,提高性能,因为“不用重新初始化对象,而是动态地获得对象运行时的状态”。

相比工厂模式,原型模式减少了子类的构建。

 

实例:

当我们出版了一本书《Python 设计模式 1.0版》,若10 年后我们觉得这本书跟不上时代了,这时候需要去重写一本《Python 设计模式 2.0版》,那么我们是完全重写一本书呢?还是在原有《Python 设计模式 1.0版》的基础上进行修改呢?当然是后者,这样会省去很多排版、添加原有知识等已经做过的工作。

又比如:想用Photoshop画一只小狗。首先创建一个比较复杂图层对象(包括背景色,画笔粗细、颜色等等),然后用该图层对象画小狗。之后我又想画一只属性相同的大狗,难道我还要在重新创建一个图层对象吗?当然不同,直接复制之前创建的就可以了。

代码实现:

from copy import copy, deepcopy

class simpleLayer:
    """
       设计一个图层对象,用background表示背景的RGBA,简单用content表示内容,除了直接绘画,还可以设置透明度。
  """
    background=[0,0,0,0]
    content="blank"
    def getContent(self):
        return self.content
    def getBackground(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)


if  __name__=="__main__":
    dog_layer=simpleLayer()
    dog_layer.paint("Dog")
    dog_layer.fillBackground([0,0,255,0])
    print("Background:",dog_layer.getBackground())
    print("Painting:",dog_layer.getContent())
    another_dog_layer=dog_layer.clone()
    # 通过复制(clone)这个动作实现画一只同样的狗
    print("Background:", another_dog_layer.getBackground())
    print("Painting:", another_dog_layer.getContent())

 

深浅拷贝:

浅拷贝会拷贝对象内容及其内容的引用或者子对象的引用,但不会拷贝引用的内容和子对象本身;而深拷贝不仅拷贝了对象和内容的引用,也会拷贝引用的内容。所以,一般深拷贝比浅拷贝复制得更加完全,但也更占资源(包括时间和空间资源)。

浅拷贝:

#浅拷贝
if  __name__=="__main__":
    dog_layer=simpleLayer()
    dog_layer.paint("Dog")
    dog_layer.fillBackground([0,0,255,0])
    print("Original Background:",dog_layer.getBackground())
    print("Original Painting:",dog_layer.getContent())
    another_dog_layer=dog_layer.clone()
    # another_dog_layer=dog_layer.deep_clone()
    another_dog_layer.setParent(128)
    another_dog_layer.paint("Puppy")
    print("Original Background:", dog_layer.getBackground())
    print("Original Painting:", dog_layer.getContent())
    print("Copy Background:", another_dog_layer.getBackground())
    print("Copy Painting:", another_dog_layer.getContent())


运行结果:

Original Background: [0, 0, 255, 0]
Original Painting: Dog
Original Background: [0, 0, 255, 128]
Original Painting: Dog
Copy Background: [0, 0, 255, 128]
Copy Painting: Puppy
可以看出在浅拷贝时setParent()方法在类another_dog_layer中并没有二次执行,而是直接从内存中dog_layer中拷贝过来(用的类dog_layer的)

 

 

深拷贝:

#深拷贝
if  __name__=="__main__":
    dog_layer=simpleLayer()
    dog_layer.paint("Dog")
    dog_layer.fillBackground([0,0,255,0])
    print("Original Background:",dog_layer.getBackground())
    print("Original Painting:",dog_layer.getContent())
    #another_dog_layer=dog_layer.clone()
    another_dog_layer=dog_layer.deep_clone()
    another_dog_layer.setParent(128)
    another_dog_layer.paint("Puppy")
    print("Original Background:", dog_layer.getBackground())
    print("Original Painting:", dog_layer.getContent())
    print("Copy Background:", another_dog_layer.getBackground())
    print("Copy Painting:", another_dog_layer.getContent())


执行结果:
Original Background: [0, 0, 255, 0]
Original Painting: Dog
Original Background: [0, 0, 255, 0]
Original Painting: Dog
Copy Background: [0, 0, 255, 128]
Copy Painting: Puppy

可以看出,再深拷贝时another_dog_layer的所有方法都是自己构建的。

 

你可能感兴趣的:(Python设计模式)