原型模式
介绍:
- 创建新的对象比较复杂时,可以利用原型模式简化对象的创建过程,同时也能够提高效率。
- 不用重新初始化对象,而是动态获取对象运行时的状态
- 如果原始对象属性发生了变化,不需要改变代码,其他克隆对象也随之发生相应变化
- 在实现克隆的时候可能需要比较复杂的代码
- 缺点:需要给每个类配置一个克隆方法,这对全新的类来说并不难,但对已有的类进行改造时,需要修改代码,违背了OCP原则
原型类
import java.io.Serializable;
public class User implements Serializable,Cloneable{
static final Long serialVersionUID = -1L;
private int id;
private String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
System.out.println("原型对象复制成功...");
return super.clone();
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
使用方:
public class Client {
public static void main(String[] args)throws Exception {
User user = new User(1,"zhangSan");
User clone = (User)user.clone();
System.out.println("两个对象是否相同 ="+(user == clone));
//对象属性修改
clone.setId(2);
clone.setName("lisi");
System.out.println("clone对象"+clone.toString());
}
}
clone方法在拷贝对象时为浅拷贝,及只能拷贝了基本数据类型和String类型的属性,引用数据类型无法拷贝。可以通过序列化和反序列化方式实现自己的深拷贝方法。
public class Group implements Serializable, Cloneable {
static final Long serialVersionUID = -1L;
private int groupId;
private User user;
public Group(int groupId, User user) {
this.groupId = groupId;
this.user = user;
}
public int getGroupId() {
return groupId;
}
public void setGroupId(int groupId) {
this.groupId = groupId;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Group{" +
"groupId=" + groupId +
", user=" + user +
'}';
}
//利用序列化和反序列化深度copy 对象包括引用类型数据都会被copy重写
public Object deepClone() {
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
//序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
return null;
}finally {
try {
bos.close();
oos.close();
bis.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用方:
public class Client {
public static void main(String[] args) {
User user = new User(1,"zhangSan");
Group group = new Group(1,user);
Group clone1 = (Group)group.deepClone();
clone1.setGroupId(2);
System.out.println(group.getUser().hashCode() + " "+clone1.getUser().hashCode());
}
}