美文网首页我爱编程
【设计模式】原型模式

【设计模式】原型模式

作者: flowerAO | 来源:发表于2018-05-26 15:52 被阅读0次

    转换阵地,用《Mastering Python Design Patterns》来作指导。

    clone()函数

    # /usr/bin/python
    # coding=utf-8
    
    
    import copy
    
    
    class A:
        def __init__(self):
            self.x = 18
            self.msg = 'Hello'
    
    
    class B(A):
        def __init__(self):
            A.__init__(self)
            self.y = 34
    
        def __str__(self):
            return '{}, {}, {}'.format(self.x, self.msg, self.y)
    
    
    if __name__ == '__main__':
        b = B()
        c = copy.deepcopy(b)
        print b
        print c
        print (b, c)
        print [i for i in str(b)]
        print [str(i) for i in (b, c)]
        print [i for i in (b, c)]
        print "%s"%c
        print "%s" % b
    
    

    输出

    18, Hello, 34
    18, Hello, 34
    (<__main__.B instance at 0x10d0edef0>, <__main__.B instance at 0x10d0edf38>)
    ['1', '8', ',', ' ', 'H', 'e', 'l', 'l', 'o', ',', ' ', '3', '4']
    ['18, Hello, 34', '18, Hello, 34']
    [<__main__.B instance at 0x10d0edef0>, <__main__.B instance at 0x10d0edf38>]
    18, Hello, 34
    18, Hello, 34
    
    Process finished with exit code 0
    
    • 方法str是一个特殊方法,它构造并返回PhoneNumber类的一个对象的字符串表示。解析器一旦遇到如下语句:
      print phone就会执行print phone.str()

    • 程序如果将PhoneNumber对象传给内建函数str(如str(phone)),或者为PhoneNumber对象使用字符串格式化运算符%(例如"%s"%phone),Python也会调用str方法

    原型模式实现

    当我们已有一个对象,并希望创建该对象的一个完整副本时,原型模式就派上用场了。在我们知道对象的某些部分会被变更但又希望保持原有对象不变之时,通常需要对象的一个副本。在这样的案例中,重新创建原有对象是没有意义的。
    当我们想复制一个复杂对象时,使用原型模式会很方便。对于复制复杂对象,我们可以将对象当做是从数据库中获取的,并引用其他一些也是从数据库中获取的对象。若通过多次重复查询数据来创建一个对象,则要做很多的工作。在这种场景下使用原型模式要方便的多。

    • copy构造一个新的复合对象后,会尽可能地将在原始对象中找到的对象的引用插入新对象中
    • deepcopy构造一个新的复合对象后,会递归地将在原始对象中找到的对象的副本插入新对象中

    两个版本的书有区别,也有大量的相似之处。如果知道两个版本的相似之处,可以先克隆一份,然后仅修改新版本与旧版本之间的不同之处。

    # /usr/bin/python
    # 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
    
    
    class main():
        b1 = Book('The C programming Language', ('Brain 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()
    

    输出

    authors: ('Brain W. Kernighan', 'Dennis M.Ritchie')
    length: 228
    name: The C programming Language
    price: 118$
    publication_date: 1978-02-22
    publisher: Prentice Hall
    tags: ('C', 'programming', 'algorithms', 'data structures')
    
    authors: ('Brain W. Kernighan', 'Dennis M.Ritchie')
    edition: 2
    length: 274
    name: The C Programming Language(ANSI)
    price: 48.99$
    publication_date: 1988-04-01
    publisher: Prentice Hall
    tags: ('C', 'programming', 'algorithms', 'data structures')
    
    ID b1 : 4340495568 != ID b2 : 4340690096
    
    Process finished with exit code 0
    

    相关文章

      网友评论

        本文标题:【设计模式】原型模式

        本文链接:https://www.haomeiwen.com/subject/ejlyjftx.html