码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式-创建型模式,原型模式(3)

时间:2018-03-07 23:55:59      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:red   list   解决   src   post   mat   区别   alice   rest   

有时,我们需要原原本本地为对象创建一个副本。举例来说,假设你想创建一个应用来存储、
分享、编辑(比如,修改、添加注释及删除)食谱。用户Bob找到一份蛋糕食谱,在做了一些改
变后,觉得自己做的蛋糕非常美味,想要与朋友Alice分享这个食谱。但是该如何分享食谱呢?如
果在与Alice分享之后,Bob想对食谱做进一步的试验,Alice手里的食谱也能跟着变化吗?Bob能
够持有蛋糕食谱的两个副本吗?对蛋糕食谱进行的试验性变更不应该对原本美味蛋糕的食谱造
成影响。
这样的问题可以通过让用户对同一份食谱持有多个独立的副本来解决。每个副本被称为一个
克隆,是某个时间点原有对象的一个完全副本。这里时间是一个重要因素。因为它会影响克隆所
包含的内容。例如,如果Bob在对蛋糕食谱做改进以臻完美之前就与Alice分享了,那么Alice就绝
不可能像Bob那样烘烤出自己的美味蛋糕,只能按照Bob原来找到的食谱烘烤蛋糕。
注意引用与副本之间的区别。如果Bob和Alice持有的是同一个蛋糕食谱对象的两个引用,那
么Bob对食谱做的任何改变,对于Alice的食谱版本都是可见的,反之亦然。我们想要的是Bob和
Alice各自持有自己的副本,这样他们可以各自做变更而不会影响对方的食谱。实际上Bob需要蛋
糕食谱的两个副本:美味版本和试验版本。

 

# coding: utf-8

import copy
from collections import OrderedDict


class Book:

    def __init__(self, name, authors, price, **rest):
        ‘‘‘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 identifier: {}.format(identifier))
        obj = copy.deepcopy(found)
        obj.__dict__.update(attr)
        return obj


def main():
    b1 = Book(The C Programming 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()

 

技术分享图片

 

设计模式-创建型模式,原型模式(3)

标签:red   list   解决   src   post   mat   区别   alice   rest   

原文地址:https://www.cnblogs.com/ydf0509/p/8525580.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!