在有些系统中,存在大量相同或类似对象的建立问题,若是用传统的构造函数来建立对象,会比较复杂且耗时耗资源,用原型模式生成对象就很高效,就像孙悟空拔下猴毛轻轻一吹就变出不少孙悟空同样简单。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】用带原型管理器的原型模式来生成包含“圆”和“正方形”等图形的原型,并计算其面积。
分析:本实例中因为存在不一样的图形类,例如,“圆”和“正方形”,它们计算面积的方法不同,因此须要用一个原型管理器来管理它们,图所示是其结构图。