【设计模式】原型模式
定义
- 原型实例指定创建对象的种类,通过拷贝这些原型创建新的对象
- 调用者不需要知道任何创建细节,不调用构造函数
- 创建型模式
类图
适用场景
- 类初始化消耗资源较多
- new产生的一个对象需要非常繁琐的过程(数据准备,访问权限等)
- 构造函数比较复杂
- 循环体中生产大量对象
代码实现
浅克隆
- 原型实现Cloneable接口
public class ConcretePrototype implements Cloneable
- 覆盖clone方法,如下所示
/**
* 浅克隆
* @return
*/
@Override
public ConcretePrototype clone() {
try {
return (ConcretePrototype) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
深克隆
- 序列化方式
/**
* 深克隆
* @return
*/
public ConcretePrototype deepClone() {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (ConcretePrototype) ois.readObject();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
优点
- 性能比使用构造器创建对象好很多。
- 将对象使用深克隆,在某些业务场景下可以辅助实现撤销操作。
缺点
- 需要为每个类配置一个clone()方法。
- 在实现深克隆的时候,当对象属性比较复杂,并且存在多重对象嵌套的时候,深克隆的代码会变得很复杂。
源码中应用
- ArrayList实现了Cloneable接口,它的clone()方法实现如下
/**
* Returns a shallow copy of this <tt>ArrayList</tt> instance. (The
* elements themselves are not copied.)
*
* @return a clone of this <tt>ArrayList</tt> instance
*/
public Object clone() {
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
通过注释可知,它是一个浅克隆
备注
- 单例和原型是互斥的关系,如果是单例则不能实现Cloneable接口。
评论区