zoukankan      html  css  js  c++  java
  • 原型模式

    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('
    ')
            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.总结

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




  • 相关阅读:
    SQLServer 知识点
    Entity转换为ViewModel时提供的一种转换方法
    Linq中IGrouping转换为IQueryable
    封装整形属性时对应到枚举
    新的转换列表方式
    工作态度
    EasyFrame
    NewCloud
    将博客搬至CSDN
    Html的语义化
  • 原文地址:https://www.cnblogs.com/vipchenwei/p/7127402.html
Copyright © 2011-2022 走看看