在有些系統中,存在大量相同或類似對象的建立問題,若是用傳統的構造函數來建立對象,會比較複雜且耗時耗資源,用原型模式生成對象就很高效,就像孫悟空拔下猴毛輕輕一吹就變出不少孫悟空同樣簡單。python
原型(Prototype)模式的定義以下:用一個已經建立的實例做爲原型,經過複製該原型對象來建立一個和原型相同或類似的新對象。函數
在這裏,原型實例指定了要建立的對象的種類。用這種方式建立對象很是高效,根本無須知道對象建立的細節。spa
例如,Windows 操做系統的安裝一般較耗時,若是複製就快了不少。在生活中複製的例子很是多,這裏不一一列舉了。操作系統
原型模式包含如下主要角色。3d
from copy import copy, deepcopy class Prototype(object): '''抽象原型類''' def clone(self): # 淺拷貝 pass def deep_clone(self): # 深拷貝 pass class Realizetype(Prototype): '''具體原型類''' cls_s = [[1, 2, 3], 4, 5, 6] def __init__(self): self.s = [[1, 2, 3], 4, 5, 6] print("具體原型類實例化成功!") def clone(self): print("具體原型類潛複製成功!") return copy(self) def deep_clone(self): print("具體原型類深複製成功!") return deepcopy(self) if __name__ == '__main__': rt = Realizetype() copy_rt = rt.clone() deep_copy_rt = rt.deep_clone() rt.s[0][1] = 10 rt.cls_s[0][1] = 10 print(rt.s, copy_rt.s, deep_copy_rt.s) print(rt.cls_s, copy_rt.cls_s, deep_copy_rt.cls_s)
具體原型類實例化成功! 具體原型類潛複製成功! 具體原型類深複製成功! [[1, 10, 3], 4, 5, 6] [[1, 10, 3], 4, 5, 6] [[1, 2, 3], 4, 5, 6] [[1, 10, 3], 4, 5, 6] [[1, 10, 3], 4, 5, 6] [[1, 10, 3], 4, 5, 6]
從結果中能夠發現,潛複製中可變元素中嵌套有可變元素,一旦嵌套中的可變元素髮生變化,潛複製的值也會發生變化,即原來的[1,2, 3]變成了[1, 10, 3]。code
可是類屬性卻會跟着變化,由於類屬性只屬於類,不屬於實例。注意這種差別只有在可變元素中發生。對象
【例1】用原型模式生成「三好學生」獎狀blog
分析:同一學校的「三好學生」獎狀除了獲獎人姓名不一樣,其餘都相同,屬於類似對象的複製,一樣能夠用原型模式建立,而後再作簡單修改就能夠了。圖 4 所示是三好學生獎狀生成器的結構圖。接口
from copy import copy class Prototype(object): def clone(self): pass class Citation(Prototype): def __init__(self, name, info, college): self.__name = name self.__info = info self.__college = college print("獎狀建立成功!") def clone(self): return copy(self) @property def name(self): return self.__name @name.setter def name(self, name): self.__name = name @property def info(self): return self.__info @info.setter def info(self, info): self.__info = info @property def college(self): return self.__college @college.setter def college(self, college): self.__college = college def show(self): print(self.__name, self.__info, self.__college) if __name__ == '__main__': st1 = Citation("zhang", "三好學生", "南京大學") st2 = st1.clone() st2.name = "wang" st2.college = "北京大學" st1.show() st2.show()
獎狀建立成功! zhang 三好學生 南京大學 wang 三好學生 北京大學
原型模式一般適用於如下場景。資源
原型模式可擴展爲帶原型管理器的原型模式,它在原型模式的基礎上增長了一個原型管理器 PrototypeManager 類。該類用 HashMap 保存多個複製的原型,Client 類能夠經過管理器的 get(String id) 方法從中獲取複製的原型。其結構圖如圖所示。
【例2】用帶原型管理器的原型模式來生成包含「圓」和「正方形」等圖形的原型,並計算其面積。
分析:本實例中因爲存在不一樣的圖形類,例如,「圓」和「正方形」,它們計算面積的方法不同,因此須要用一個原型管理器來管理它們,圖所示是其結構圖。