原型模式
原型模式的优点:
- Java 自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良。
- 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。
原型模式的缺点:
- 需要为每一个类都配置一个 clone 方法
- clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则。
- 当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深克隆、浅克隆需要运用得当。
Java 提供了对象的 clone() 方法,所以用 Java 实现原型模式很简单。
原型模式的克隆分为浅克隆和深克隆。
- 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
- 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
//浅克隆
//对象
public class Video implements Cloneable{
private String name;
private Date createTime;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Video() {
}
public Video(String name, Date createTime) {
this.name = name;
this.createTime = createTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "Video{" +
"name='" + name + '\'' +
", createTime=" + createTime +
'}';
}
}
//用户
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//原型对象 v1
Date date = new Date();
Video v1 = new Video("gwt",date);
Video v2 = (Video) v1.clone(); //v2克隆v1
System.out.println("v1->"+v1);
System.out.println("v2->"+v2);
System.out.println("==============");
date.setTime(22111111);
System.out.println("v1->"+v1);
System.out.println("v2->"+v2);
}
}
**结果:
v1->Video{name='gwt', createTime=Wed Sep 01 21:54:38 CST 2021}
v2->Video{name='gwt', createTime=Wed Sep 01 21:54:38 CST 2021}
==============
v1->Video{name='gwt', createTime=Thu Jan 01 14:08:31 CST 1970}
v2->Video{name='gwt', createTime=Thu Jan 01 14:08:31 CST 1970}**
//深克隆
//对象
public class Video implements Cloneable{
private String name;
private Date createTime;
@Override
public Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
Video v = (Video) obj;
//将对象属性也进行克隆
v.createTime = (Date) this.createTime.clone();
return obj;
}
public Video() {
}
public Video(String name, Date createTime) {
this.name = name;
this.createTime = createTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "Video{" +
"name='" + name + '\'' +
", createTime=" + createTime +
'}';
}
}
//用户
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//原型对象 v1
Date date = new Date();
Video v1 = new Video("gwt",date);
Video v2 = (Video) v1.clone(); //v2克隆v1
System.out.println("v1->"+v1);
System.out.println("v2->"+v2);
System.out.println("==============");
date.setTime(22111111);
System.out.println("v1->"+v1);
System.out.println("v2->"+v2);
}
}
结果:
**v1->Video{name='gwt', createTime=Wed Sep 01 22:04:09 CST 2021}
v2->Video{name='gwt', createTime=Wed Sep 01 22:04:09 CST 2021}
==============
v1->Video{name='gwt', createTime=Thu Jan 01 14:08:31 CST 1970}
v2->Video{name='gwt', createTime=Wed Sep 01 22:04:09 CST 2021}**