设计模式-原型
一、简介
简单来说,就是通过复制一个已经存在的对象来创建一个新对象。但是这个复制是深层的复制,对象及对象中的所有嵌套对象都是指向不同的内存地址的。
基本类图结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DUJ46vbU-1687868378930)(https://note.youdao.com/yws/res/29063/WEBRESOURCEb7969b614ba859e32c8cfaa65efb4534)]
二、在Java中通过浅克隆实现
1.代码示例
/**
* 通过java提供的浅克隆来实现原型的示例
*/
public class Car implements Cloneable {
public static class Engine {
public int power = 1000;
}
public int speed = 100;
public Engine engine = new Engine();
public Car clone() throws CloneNotSupportedException {
return (Car) super.clone();
}
public static void main(String[] args) {
Car carPrototype = new Car();
System.out.println("carPrototype-before:speed:" + carPrototype.speed + ",power:" + carPrototype.engine.power);
try {
Car carShallowClone = carPrototype.clone();
carShallowClone.speed = 200;
carShallowClone.engine.power = 2000;
System.out.println("carPrototype-afterShallow:speed:" + carPrototype.speed + ",power:" + carPrototype.engine.power);
System.out.println("carShallowClone:speed:" + carShallowClone.speed + ",power:" + carShallowClone.engine.power);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
2.输出分析
speed作为Car的直接属性且是基本数据类型,super.clone()方法为其开辟了新的存储地址,clone后的对象与原对象互不干扰,修改不互不影响。
engine是嵌套对象,super.clone()方法并没有在复制一个新的engine对象,克隆后的car与原型的car中的engine是共用同一个对象的,修改克隆后car中的engine的power值会影响原型中对应的值。
三、实现深复制-序列化
1.代码示例
/**
* 通过序列化深克隆来实现原型的示例
*/
public class Car implements Cloneable, Serializable {
public static class Engine implements Serializable {
public int power = 1000;
}
public int speed = 100;
public Engine engine = new Engine();
public Car clone() {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(this);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream objIn = new ObjectInputStream(in);
return (Car) objIn.readObject();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
Car carPrototype = new Car();
System.out.println("carPrototype-before:speed:" + carPrototype.speed + ",power:" + carPrototype.engine.power);
Car carDeepClone = carPrototype.clone();
carDeepClone.speed = 200;
carDeepClone.engine.power = 2000;
System.out.println("carPrototype-afterDeep:speed:" + carPrototype.speed + ",power:" + carPrototype.engine.power);
System.out.println("carDeepClone:speed:" + carDeepClone.speed + ",power:" + carDeepClone.engine.power);
}
}
2.输出分析
观察输出可以发现,不管是直接基本属性speed还是嵌套的engine中的power,克隆后的car和原型car都互不干扰,修改互不影响。