原型模式(Prototype Pattern)
原型模式用于创建重复的对象,同时又能保证性能,属于创建型模式。
在开发过程中,需要创建多个数据相同的对象,每次使用new创建开销大,可使用对象克隆以先创建出来的原型为模板,进行对象复制,提高了创建效率。
例如:写简历,写一份,复制多份。奖状,复制多个学校等相关信息相同的奖状,颁发给不同的人,只需改他们各自不同的信息即可。一般情况下相同的信息多于不同的信息。细胞分裂。
原型模式包含如下角色:
1.抽象原型类:规定了具体原型对象必须实现的clone()方法
2.具体原型类:实现抽象原型类clone()方法,它是可被复制的对象
3.访问类:使用具体原型类中的clone()方法来复制新的对象
原型模式分为:
1.浅克隆:创建一个新对象,对象指向对象的内存地址。
2.深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不在指向原有对象地址
具体看:克隆对象?-优快云博客
优点:
1.性能提高
2.逃避构造函数的约束
缺点:
1.配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但是对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候
2.必须实现Cloneable接口
案例一:
/*
Cloneable 为抽象对象
Resume为原型对象
*/
public class Resume implements Cloneable {
public Resume() {
System.out.println("原型对象Resume构造方法");
}
@Override
protected Resume clone() throws CloneNotSupportedException {
System.out.println("克隆对象");
return (Resume)super.clone();
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Resume resume = new Resume();
Resume clone = resume.clone();
System.out.println("原型对象与克隆对象:"+(resume==clone));
}
}
运行结果:
案例二:
public class Citation implements Cloneable{
String schoolName;
Stuent stuent;
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
public Stuent getStuent() {
return stuent;
}
public void setStuent(Stuent stuent) {
this.stuent = stuent;
}
public void show(){
System.out.println(schoolName+"2023年第一学期三好学生,班级"+stuent.getClassName()+"姓名:"+stuent.getName());
}
@Override
protected Citation clone() throws CloneNotSupportedException {
Citation citation = (Citation)super.clone();
Stuent stuent = (Stuent) citation.stuent.clone();
citation.setStuent(stuent);
return citation;
}
}
public class Stuent implements Cloneable{
private String name;
private String className;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
@Override
protected Stuent clone() throws CloneNotSupportedException {
return (Stuent) super.clone();
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Citation citation = new Citation();
citation.setSchoolName("振华小学");
Stuent stuent = new Stuent();
stuent.setClassName("一年一班");
stuent.setName("李明");
citation.setStuent(stuent);
Citation citation1 = citation.clone();
Stuent stuent1 = citation1.getStuent();
stuent1.setClassName("一年二班");
stuent1.setName("李磊");
citation1.setStuent(stuent1);
citation.show();
citation1.show();
}
}
运行结果: