原型模式的注意事项和细节
- 创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提 高效率
- 不用重新初始化对象,而是动态地获得对象运行时的状态
- 如果原始对象发生变化(增加或者减少属性),其它克隆对象的也会发生相应的变化, 无需修改代码
- 在实现深克隆的时候可能需要比较复杂的代码
- 缺点:需要为每一个类配备一个克隆方法,这对全新的类来说不是很难,但对已有 的类进行改造时,需要修改其源代码,违背了ocp原则,这点请同学们注意
沈拷贝之序列化拷贝
复制一个对象,连带属性的值复制出来,属性如果是引用类型,那么是一个地址,用了另外的空间。
一次代码终生使用【极荐】
代码实现(原型是重点)
原型类
package com.yuan.dp.prototype.domain;
import java.io.*;
public class Chicken implements Serializable {
String name;
String hobby;
Friend friend;
public Chicken(String name, String hobby, Friend friend) {
this.name = name;
this.hobby = hobby;
this.friend = friend;
}
@Override
public String toString() {
return "Chicken{" +
"name='" + name + '\'' +
", hobby='" + hobby + '\'' +
", friend=" + friend.hashCode() +
'}';
}
/**
* 第2种 深拷贝方法 【序列化】
*
* @return
*/
@Override
public Chicken clone() {
ByteArrayOutputStream bos;
ByteArrayInputStream bis;
ObjectOutputStream oos;
ObjectInputStream ois;
try {
//序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
//当前对象以流的方式输出【一次将本类相关的所有类型都拿过来,再多的属性也不变代码】
oos.writeObject(this);
//反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
Chicken chicken = (Chicken) ois.readObject();
return chicken;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
} finally {
//关流
}
}
}
引用类型属性类
package com.yuan.dp.prototype.domain;
import java.io.Serializable;
public class Friend implements Cloneable, Serializable {
public String name ;
public String hobby ;
/**
* 如果没有引用类型 就用浅拷贝 默认的
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Friend clone() throws CloneNotSupportedException {
Friend friend = (Friend) super.clone();
return friend;
}
}
测试
package com.yuan.dp.prototype;
import com.yuan.dp.prototype.domain.Chicken;
import com.yuan.dp.prototype.domain.Friend;
public class Prototype_3 {
public static void main(String[] args) {
Friend friend = new Friend();
Chicken chicken_1 = new Chicken("小红", "睡觉", friend);
System.out.println("chicken_1 = " + chicken_1);
//chicken_1 = Chicken{name='小红', hobby='睡觉', friend=42121758}
Chicken chicken_2 = chicken_1.clone();
System.out.println("chicken_2 = " + chicken_2);
//chicken_2 = Chicken{name='小红', hobby='睡觉', friend=1810132623}
System.out.println(chicken_1 == chicken_2);
//false
}
}