python 設計模式之原型模式 Prototype Pattern

#引入

例子1:html

孫悟空拔下一嘬猴毛,輕輕一吹就會變出好多的孫悟空來。python

 

例子2:寄個快遞
下面是一個郵寄快遞的場景:
「給我寄個快遞。」顧客說。
「寄往什麼地方?寄給……?」你問。
「和上次差很少同樣,只是郵寄給另一個地址,這裏是郵寄地址……」顧客一邊說一邊把寫有郵寄地址的紙條給你。
「好!」你愉快地答應,由於你保存了用戶的之前郵寄信息,只要複製這些數據,而後經過簡單的修改就能夠快速地建立新的快遞數據了。
編程

 

 

# 原型模式概念

用原型實例指定建立對象的種類,並經過複製這些原型建立新的對象設計模式

是建造者模式安全

 

 #原型模式使用場景

1)資源優化場景。類初始化須要消耗很是多的資源,這個資源包括數據,硬件資源等,可經過原型複製避免這些消耗
2)經過new產生一個對象須要很是繁瑣的數據準備或訪問權限,這時可使用原型模式
3)一個對象須要提供給其餘對象訪問,並且每一個調用者可能都須要修改其值時?能夠考慮使用原型模式複製多個對象供調用者使用,即保護性拷貝ide

4)性能和安全要求的場景。函數

 

 

 

 #原型模式的優勢

1)當建立的對象實例較爲複雜的時候,使用原型模式能夠簡化對象的建立過程!
2)擴展性好,因爲寫原型模式的時候使用了抽象原型類,在客戶端進行編程的時候能夠將具體的原型類經過配置進行讀取。
2)可使用深度克隆來保存對象的狀態,使用原型模式進行復制。當你須要恢復到某一時刻就直接跳到。好比咱們的idea種就有歷史版本,或則SVN中也有這樣的操做。很是好用!

性能

 #原型模式的缺點

1)配備克隆方法須要對類的功能進行通盤考慮,這對於全新的類不是很難,但對於已有的類不必定很容易,特別當一個類引用不支持串行化的間接對象,或者引用含有循環結構的時候。優化

2)必須實現 Cloneable 接口。idea

 

#原型模式的角色

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

相關文章
相關標籤/搜索