原型模式
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
使用场景
1.在需要一个类的大量对象的时候,使用原型模式是最佳选择,因为原型模式是在内存中对这个对象进行拷贝,要比直接new这个对象性能要好很多,在这种情况下,需要的对象越多,原型模式体现出的优点越明显。
2.如果一个对象的初始化需要很多其他对象的数据准备或其他资源的繁琐计算,那么可以使用原型模式。
3.当需要一个对象的大量公共信息,少量字段进行个性化设置的时候,也可以使用原型模式拷贝出现有对象的副本进行加工处理。
浅拷贝原型模式
java的Object类的clone方法是浅拷贝,当类中存在对象引用字段时,拷贝后的两个对象中的引用字段将指向同一对象。
原型类
//原型类
public class HomeWork implements Cloneable{
private String student; //学生
private String teacher; //老师
private String content; //内容
public String getStudent() { return student; }
public void setStudent(String student) { this.student = student; }
public String getTeacher() { return teacher; }
public void setTeacher(String teacher) { this.teacher = teacher; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
@Override
public String toString() {
return "HomeWork"+super.toString()+"{" + "student='" + student + '\'' +
", teacher='" + teacher + '\'' + ", content='" + content + '\'' + '}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
通过继承Cloneable接口提示此类可以进行克隆,并重写父类的clone方法来实现克隆。
测试类
//测试类
class Test {
public static void main(String[] args) throws CloneNotSupportedException {
List<HomeWork> homeWorks=new LinkedList<>(); //储存整个班级的所有作业
HomeWork homeWork=new HomeWork(); //创建一个作业模板
homeWork.setTeacher("me"); //设置模板的教师名称
homeWork.setContent("xxxx"); //设置作业内容
for(int a=0;a<5;a++) { //循环创建每个同学的作业
HomeWork homeWork1=(HomeWork) homeWork.clone(); //克隆作业模板
homeWork.setStudent("studnet"+a); //设置作业的学生
homeWorks.add(homeWork1);
}
}
}
深拷贝原型模式
java的Object类的clone方法是浅拷贝,当类中存在对象引用字段时,通过对类中的引用字段分别拷贝来实现深拷贝。
原型类
//原型类
class HomeWork implements Cloneable{
private String student; //学生
private String teacher; //老师
private String content; //内容
private Date limitDate; //截至时间,!对象引用
public String getStudent() { return student; }
public void setStudent(String student) { this.student = student; }
public String getTeacher() { return teacher; }
public void setTeacher(String teacher) { this.teacher = teacher; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public Date getLimitDate() { return limitDate; }
public void setLimitDate(Date limitDate) { this.limitDate = limitDate; }
@Override
public String toString() {
return "HomeWork"+super.toString()+"{" +
"student='" + student + '\'' +", teacher='" + teacher + '\'' +
", content='" + content + '\'' +", limitDate=" + limitDate + '}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
HomeWork homeWork = (HomeWork) super.clone(); //先克隆整体
homeWork.limitDate = (Date) limitDate.clone(); //再对象引用进行单独克隆
return homeWork;
}
}
通过先克隆整个对象,之后对对象引用字段单独克隆来避免浅克隆。
测试类
//测试类
class Test {
public static void main(String[] args) throws CloneNotSupportedException {
List<HomeWork> homeWorks=new LinkedList<>();
HomeWork homeWork=new HomeWork();
homeWork.setTeacher("me");
homeWork.setContent("xxxx");
homeWork.setLimitDate(new Date());
for(int a=0;a<5;a++) {
HomeWork homeWork1=(HomeWork) homeWork.clone();
homeWork.setStudent("studnet"+a);
homeWorks.add(homeWork1);
}
}
}