原型模式
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。
原型模式有2种实现方式,浅克隆和深克隆。
浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
由于 Java 提供了对象的 clone() 方法,所以用 Java 实现原型模式很简单。
实现Cloneable接口,重写clone方法。
例如,user类:
/**
* 姓名
*/
private String name;
/**
* 电话
*/
private String phone;
/**
* 拥有的物品
*/
private List<String> have = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public List<String> getHave() {
return have;
}
public void setHave(List<String> have) {
this.have = have;
}
@Override
protected User clone() {
// 浅克隆
try {
return (User)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
// // 深克隆,需要实现序列化接口
// ByteArrayOutputStream bos = new ByteArrayOutputStream();
// try {
// ObjectOutputStream oos = new ObjectOutputStream(bos);
// oos.writeObject(this);
// ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
// ObjectInputStream ois = new ObjectInputStream(bis);
// return (User) ois.readObject();
// } catch (IOException | ClassNotFoundException e) {
// e.printStackTrace();
// return null;
// }
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", phone='" + phone + '\'' +
", have=" + have +
'}';
}
使用方式
// 原型对象
User sourceUser = new User();
sourceUser.setName("小周");
User newUser = sourceUser.clone();
newUser.getHave().add("车");
System.out.println("原来对象:"+sourceUser);
System.out.println("复制对象:"+ newUser);
System.out.println(sourceUser.getHave().equals(newUser.getHave()) );
浅克隆结果:
深克隆结果:
需要注意的是深克隆需要实现序列化接口。
我大致画了一张图做说明。
参考资料:
1.http://c.biancheng.net/view/1343.html
2.代码地址:https://gitee.com/zhoujie1/design-mode-and-principle.git