1.原型模式的定义
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象
2.原型模式的优点与缺点
优点:
- Java 自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良。
- 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。
缺点:
- 需要为每一个类都配置一个 clone 方法
- clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则。
- 当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深克隆、浅克隆需要运用得当。
- 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
- 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
3.浅克隆
package prototype;
import java.util.Date;
/**
* 原型模式
* 1.实现接口 Cloneable
* 2.重写方法 clone()
* @author Admin
*
*/
public class Video implements Cloneable{
private String name;
private Date createTime;
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 + "]";
}
//重写克隆方法
@Override
protected Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
package prototype;
import java.util.Date;
/**
* 浅克隆
* @author Admin
*
*/
public class VideoClone {
public static void main(String[] args) throws CloneNotSupportedException {
// 原型對象v1
Date date=new Date();
Video v1=new Video("斗罗大陆",date);
// v1克隆v2
Video v2=(Video) v1.clone();
System.out.println("v1:"+v1);
System.out.println("v2:"+v2);
System.out.println("=====================");
//修改date
date.setTime(2222211);
System.out.println("v1:"+v1);
System.out.println("v2:"+v2);
}
}
v1:Video [name=斗罗大陆, createTime=Mon Nov 09 18:25:13 CST 2020]
v2:Video [name=斗罗大陆, createTime=Mon Nov 09 18:25:13 CST 2020]
=====================
v1:Video [name=斗罗大陆, createTime=Thu Jan 01 08:37:02 CST 1970]
v2:Video [name=斗罗大陆, createTime=Thu Jan 01 08:37:02 CST 1970]
4.深克隆
package prototype;
import java.util.Date;
/**
* 深克隆
* @author Admin
*
*/
public class Video2 implements Cloneable{
private String name;
private Date createTime;
public Video2() {
}
public Video2(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 + "]";
}
//重写克隆方法
@Override
protected Object clone() throws CloneNotSupportedException{
Object obj=super.clone();
//实现深克隆()----也可以序列化,反序列
Video2 v=(Video2)obj;
//将对象的属性也进行克隆
v.createTime=(Date) this.createTime.clone();
return obj;
}
}
package prototype;
import java.util.Date;
/**
*
* @author Admin
*
*/
public class VideoClone2 {
public static void main(String[] args) throws CloneNotSupportedException {
// 原型對象v1
Date date=new Date();
Video2 v1=new Video2("斗罗大陆",date);
// v1克隆v2
Video2 v2=(Video2) v1.clone();
System.out.println("v1:"+v1);
System.out.println("v2:"+v2);
System.out.println("=====================");
//修改date
date.setTime(2222211);
System.out.println("v1:"+v1);
System.out.println("v2:"+v2);
}
}
v1:Video [name=斗罗大陆, createTime=Mon Nov 09 18:26:40 CST 2020]
v2:Video [name=斗罗大陆, createTime=Mon Nov 09 18:26:40 CST 2020]
=====================
v1:Video [name=斗罗大陆, createTime=Thu Jan 01 08:37:02 CST 1970]
v2:Video [name=斗罗大陆, createTime=Mon Nov 09 18:26:40 CST 2020]