• python 设计模式之原型模式 Prototype Pattern


    #引入

    例子1:

    孙悟空拔下一嘬猴毛,轻轻一吹就会变出好多的孙悟空来。

     

    例子2:寄个快递
    下面是一个邮寄快递的场景:
    “给我寄个快递。”顾客说。
    “寄往什么地方?寄给……?”你问。
    “和上次差不多一样,只是邮寄给另外一个地址,这里是邮寄地址……”顾客一边说一边把写有邮寄地址的纸条给你。
    “好!”你愉快地答应,因为你保存了用户的以前邮寄信息,只要复制这些数据,然后通过简单的修改就可以快速地创建新的快递数据了。

     

     

    # 原型模式概念

    用原型实例指定创建对象的种类,并通过复制这些原型创建新的对象

    是建造者模式

     

     #原型模式使用场景

    1)资源优化场景。类初始化需要消耗非常多的资源,这个资源包括数据,硬件资源等,可通过原型复制避免这些消耗
    2)通过new产生一个对象需要非常繁琐的数据准备或访问权限,这时可以使用原型模式
    3)一个对象需要提供给其他对象访问,而且每个调用者可能都需要修改其值时?可以考虑使用原型模式复制多个对象供调用者使用,即保护性拷贝

    4)性能和安全要求的场景。

     

     

     

     #原型模式的优点

    1)当创建的对象实例较为复杂的时候,使用原型模式可以简化对象的创建过程!
    2)扩展性好,由于写原型模式的时候使用了抽象原型类,在客户端进行编程的时候可以将具体的原型类通过配置进行读取。
    2)可以使用深度克隆来保存对象的状态,使用原型模式进行复制。当你需要恢复到某一时刻就直接跳到。比如我们的idea种就有历史版本,或则SVN中也有这样的操作。非常好用!

     #原型模式的缺点

    1)配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。

    2)必须实现 Cloneable 接口。

     

    #原型模式的角色

    1)抽象原型(Prototype)角色:规定了具体原型对象必须实现的接口(如果要提供深拷贝,则必须具有实现clone的规定)

    2)具体原型(ConcretePrototype):从抽象原型派生而来,是客户程序使用的对象,即被复制的对象,需要实现抽象原型角色所要求的接口。

    3)客户(Client)角色:使用原型对象的客户程序

     

     

     

    #原型模式的主意事项

    对象拷贝的时候构造函数是不会执行的,原因在于拷贝是直接在堆中进行,这其实也可以理解,new的时候,JVM要走一趟类加载流程,这个流程非常麻烦,在类加载流程中会调用构造函数,最后生成的对象会放到堆中,而拷贝就是直接拷贝堆中的现成的二进制对象,然后重新一个分配内存块。 

     

     

    #浅克隆

    仅仅复制所克隆的对象,而不复制它所引用的对象。

    被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。

     

    #深克隆

    把要复制的对象所引用的对象都复制了一遍。

    那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。

     

    #举个例子

    这个设计模式很好理解,而且已经嵌入到了语言中,拿andy的例子作参考

    from copy import copy,deepcopy
    
    #原型抽象类
    
    class Prototype:
        def clone(slef):
            pass
        def deep_clone(self):
            pass
    
    #workexperience类
    class WorkExperience:
        def __init__(self):
            self.timearea=''
            self.company=''
    
        def set_workexperience(self,timearea,company):
            self.timearea=timearea
            self.company=company
    
    #Resume类
    class Resume(Prototype):
        def __init__(self,name):
            self.name=name
            self.workexperience=WorkExperience()
    
        def set_personinfo(self,sex,age):
            self.sex=sex
            self.age=age
            pass
    
        def set_workexperience(self,timearea,company):
            self.workexperience.set_workexperience(timearea,company)
        def display(self):
            print(self.name)
            print(self.sex,self.age)
            print('work experience',self.workexperience.timearea,self.workexperience.company)
    
        def clone(self):
             return copy(self)
    
        def deep_clone(self):
            return deepcopy(self)
    
    if __name__=='__main__':
       obj1=Resume('uu')
        obj2=obj1.clone()
        obj3=obj1.deep_clone()
    
        obj1.set_personinfo('male',28)   
        obj1.set_workexperience('2001-2003','developing')
        obj2.set_personinfo('male',26)   
        obj2.set_workexperience('2004-2006','BA')
        obj3.set_personinfo('male',26)   
        obj3.set_workexperience('2011-2012','testing')
    
        obj1.display()
        obj2.display()
        obj3.display()
        
    

     

    #参考

    https://zhidao.baidu.com/question/569131711.html

    https://blog.csdn.net/weixin_30416497/article/details/96400396

    https://blog.csdn.net/asffghfgfghfg1556/article/details/81702164

    https://blog.csdn.net/qq_40709468/article/details/82316418

    https://www.runoob.com/design-pattern/prototype-pattern.html

    https://www.cnblogs.com/fengyumeng/p/10646487.html

    https://blog.51cto.com/9291927/1970104

    https://www.cnblogs.com/onepiece-andy/p/python_prototype_pattern.html

     

     

  • 相关阅读:
    根据IP头格式 写sniff
    双零碎安设Linux之后找不到Windows分区
    Oracle的共享封锁 独有封锁和共享更新封锁 (3)
    设置配备部署Windows与Linux平台的DATA GURAD (1)
    GTick 桌面节拍器
    在文本终端怎样查看上一屏内容(终端回滚快捷键)
    肃清Cache影响手动逼迫革新Buffer Cache
    Oracle数据库无法加载_OraMTS_的处理赏罚设置装备安置
    Linux操纵琐细下确立DBCA报错的料理要领
    设置Windows与Linux平台的DATA GURAD (2)
  • 原文地址:https://www.cnblogs.com/baxianhua/p/11498432.html
Copyright © 2020-2023  润新知