原型也是一种创建型模式,考虑下面的场景:
一个类有1,2,3,4,5,6,7,8种状态,在运行过程中经过了以下1->2->3->4的状态转换,且进入到状态4时必须要经过1,2,3的状态转换。
在进入状态4后,可以向5,6,7,8状态转换。
此时要对此对象做白盒测试,1->4是一个固定的流程,很显然,从一个状态已经到4的对象开始复制一堆对象开始去做测试比new一堆对象再分别切换到5,6,7,8要方便得多。
Prototype跟其他创建型模式相比最大的特点就是复制对象,保留已有对象的状态。
在C++中使用拷贝构造函数就可以实现此功能。
class Prototype
{
public:
Prototype();
Prototype(const Prototype& prot) {
name = new char[strlen(prot.name) + 1];
strcpy(name, prot.name);
printf("copy constructor!\n");
}
private:
char *name;
};
而Python则可以用更简单的方式deepcopy做到
import copy
class dp(object):
def __init__(self):
self.x = 100
class Handler(object):
def __init__(self):
self.x = 100
self.dp = dp()
class Prototype(object):
def __init__(self):
self.x = 100
self.h = Handler()
if __name__ == '__main__':
p = Prototype()
pa = p
ps = copy.copy(p)
pd = copy.deepcopy(p)
p.x = 120
p.h.x = 120
p.h.dp.x = 120
print(p.x, p.h.x, p.h.dp.x)
print(pa.x, pa.h.x, pa.h.dp.x)
print(ps.x, ps.h.x, ps.h.dp.x)
print(pd.x, pd.h.x, pd.h.dp.x)
打印结果如下, 可以看到=号的结果只是同样的引用,copy重新生成了Prototype,但是Handler也是同样引用;而deepcopy则是逐级重新了新的对象:
(120, 120, 120)
(120, 120, 120)
(100, 120, 120)
(100, 100, 100)