设计模式之原型模式
原型模式也是一种类创建型模式,对于原型模式,其实就是简单的C++
中的拷贝构造函数,因此这里不再举情景模式。
定义
使用原型实例创建对象的种类,并通过拷贝这些原型创建新的对象。
Java中的原型模式
其实Java中,对原型模式最原生的支持便是Cloneable
接口,Cloneable
接口作为一个标记型接口,里面没有任何方法,不过如果未实现该接口的类被调用了clone()
方法的话,会抛出CloneNotSupportedException
异常,不过clone()
方法默认是protected
的,因此一般不会有这种问题出现。
对于实现clone()
的方法,一般需要满足以下几个条件:其中前两个为必要条件,第三个可选。
- 对任何的对象x,都有:
x.clone()!=x
。换言之,克隆对象与原对象不是同一个对象。 -
对任何的对象x,都有:
x.clone().getClass() == x.getClass()
,换言之,克隆对象与原对象的类型一样。 -
如果对象
x
的equals()
方法定义其恰当的话,那么x.clone().equals(x)
应当成立的
虽然说Java
中的clone()
是用来支持原型模式的,但是在《Effective Java》第十三章中提出,除了数组,最好都不要使用此方法,理由如下:
- 正如继承一样,在子类的构造方法会默认并强制首先调用父类的构造方法,但是对于
clone()
并没有此语法强制规定,因此父类不一定实现了Cloneable
接口,这样将会导致clone
出来的对象不完整 clone()
可能会破坏类中某些不可变对象的隐藏属性clone()
方法再带会抛出异常,不方便处理
等等。
总之,clone()
方法会带来很多不方便之处,并且clone()
方法仅仅是简单的浅拷贝.
因此,最好使用像C++
一样提供一个拷贝构造方法
或者静态工厂来实现原型模式
应用场景
原型模式一般应用在需要创建一个和原型对象一模一样的对象的时候