介绍
原型模式,用原型实例指定对象创建对象的种类,并且通过拷贝这些原型对象创建新对象。
代码示例
原型抽象类
public abstract class Prototype implements Cloneable {
private String id;
public Prototype(String id) {
this.id = id;
}
public String getId() {
return id;
}
// 用了复制对象本身
public abstract Prototype Clone();
}
本身继承Cloneable 接口实现浅拷贝
public class ConcretePrototypeA extends Prototype {
public ConcretePrototypeA(String id) {
super(id);
}
@Override
public Prototype Clone() {
try {
return (Prototype) this.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
使用的时候只要调用Colne方法就可以完成对象的复制。
public static void main(String[] args) {
ConcretePrototypeA cp = new ConcretePrototypeA("owen");
ConcretePrototypeA cp2 = (ConcretePrototypeA) cp.Clone();
System.out.println(cp2.getId());
}
优化
实现Cloneable只能实现浅拷贝,如果是引用类型,复制过来的是指针,而不是对象,一个值修改后,其他的也会变化。
ConcretePrototypeA 加入一个对象ObjA
public static void main(String[] args) {
ConcretePrototypeA cp = new ConcretePrototypeA("owen");
ObjB objB = new ObjB("objB");
ObjA objA = new ObjA();
objA.obj = objB;
objA.name = "objA name";
cp.setObj(objA);
ConcretePrototypeA cp2 = (ConcretePrototypeA) cp.Clone();
System.out.println(cp2.getObj() == cp.getObj());
System.out.println(cp2.getObj().name);
objA.name = "objA name change";
System.out.println(cp2.getObj().name);
}
输出
true //表示是同一个对象
objA name
objA name change // cp的值发生变化,cp2也会相应变化
Java实现深拷贝,需要将引用类型的对象实现Cloneable接口,并复写clone()
@Override
protected Object clone() throws CloneNotSupportedException {
Prototype type = (Prototype) super.clone();
type.setObj((ObjA) this.obj.clone());
return type;
}
输出
false
objA name
objA name