例子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