原型模式

1.定义

 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

2.类图

3.副本与引用的区别

    下图展示了副本与引用的区别:

      

  对引用的操作,也就是对原来真正的数据进行操作。

  而对副本的操作,对原来真正的数据并不影响。

4.代码示例:  

  原型设计模式帮助我们创建一个对象的的克隆,其最简单的形式就是一个clone() 函数,接受一个对象作为输入参数,返回输入对象的一个副本。

  实例:

from collections import OrderedDict
import copy

class Book:
    def __init__(self,name,authors,price,**rest):
        self.name = name
        self.authors = authors
        self.price = price
        self.__dict__.update(rest)  # 注意使用

    def __str__(self):
        mylist = []
        ordered = OrderedDict(sorted(self.__dict__.items()))
        for i in ordered.keys():
            mylist.append('{}:{}'.format(i,ordered[i]))
            if i == 'price':
                mylist.append('$')
            mylist.append('\n')
        return ''.join(mylist)


class Prototype:
    def __init__(self):
        self.objects = dict()

    def register(self,identifier,obj):
        self.objects[identifier] = obj

    def unregister(self,identifier):
        del self.objects[identifier]

    def clone(self,identifier,**attr):
        found = self.objects.get(identifier)
        if not found:
            raise ValueError('Incorrect object')
        obj = copy.deepcopy(found)
        obj.__dict__.update(attr)
        return obj

def main():
    b1 = Book('the c programmng language',('Brian W. Kernighan', 'Dennis M.Ritchie'),
 price=118, publisher='Prentice Hall', length=228, publication_date='1978-02-22',
 tags=('C', 'programming', 'algorithms', 'data structures'))
    prototype = Prototype()
    cid = 'k&r-first'
    prototype.register(cid,b1)
    b2 = prototype.clone(cid,name='The C Programming Language(ANSI)', price=48.99,
 length=274, publication_date='1988-04-01', edition=2)
    for i in (b1,b2):
        print(i)

    print("ID b1:{} != ID b2: {}".format(id(b1),id(b2)))

if __name__ == '__main__':
    main()

5.优点

  使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单

6.注意事项

  • 使用原型模式复制对象不会调用类的构造方法。因为对象的复制是通过调用Object类的clone方法来完成的,它直接在内存中复制数据,因此不会调用到类的构造方法。不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。
  • 深拷贝与浅拷贝。Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝。

7.总结

  原型模式用于创建对象的完全副本。创建一个对象的副本可以指代以下两件事情:
    当创建一个浅副本时,副本依赖引用
    当创建一个深副本时,副本复制所有东西
  第一种情况中,我们关注提升应用性能和优化内存使用,在对象之间引入数据共享,但需要
小心地修改数据,因为所有变更对所有副本都是可见的。
  第二种情况中,我们希望能够对一个副本进行更改而不会影响其他对象。




posted @ 2017-07-06 17:14  看雪。  阅读(250)  评论(0编辑  收藏  举报