原型模式属于23种设计模式中创建型模式之一,指利用已有的对象实例,去构造(复制)一个一模一样的实例化对象,言简意赅。
上代码:
@AllArgsConstructor
@Getter
@Setter
@ToString
class Student implements Cloneable{
private String name;
private int age;
private Score score;
@Override
protected Object clone() throws CloneNotSupportedException {
System.out.println(this.name+"被复制了");
return super.clone();
}
}
@AllArgsConstructor
@Getter
@Setter
@ToString
class Score{
private int chinese;
private int math;
}
public class Demo {
public static void main(String[] args) throws CloneNotSupportedException {
Student student1 = new Student("张三",18,new Score(80,90));
Student student2 = student1;
Student student3 = (Student)student1.clone();
System.out.println("student1 : "+student1 );
System.out.println("student2 : "+student2 );
System.out.println("student3 : "+student3 );
System.out.println("==============================");
System.out.println("student1 == student2 : "+(student1 == student2));
System.out.println("student1 == student3 : "+(student1 == student3));
System.out.println("==============================");
System.out.println("student1.hashCode() : "+student1.hashCode());
System.out.println("student2.hashCode() : "+student2.hashCode());
System.out.println("student3.hashCode() : "+student3.hashCode());
System.out.println("==============================");
System.out.println(student1.getClass());
System.out.println(student2.getClass());
System.out.println(student3.getClass());
System.out.println(student1.getScore() == student2.getScore());
System.out.println(student1.getScore() == student3.getScore());
}
}
其中使用lombok的插件,@AllArgsConstructor,@Getter @Setter @ToString添加全参构造器,Getter,Setter和ToString方法。
现有学生类Student实现了Cloneable接口,学生具有姓名,年龄,分数的属性,其中分数封装为Score对象,包括语文和数学。
输出结构如下:
student1 : Student(name=张三, age=18, score=Score(chinese=80, math=90))
student2 : Student(name=张三, age=18, score=Score(chinese=80, math=90))
student3 : Student(name=张三, age=18, score=Score(chinese=80, math=90))
==============================
student1 == student2 : true
student1 == student3 : false
==============================
student1.hashCode() : 1349393271
student2.hashCode() : 1349393271
student3.hashCode() : 1338668845
==============================
class com.example.study.DesignPattern.原型模式.Student
class com.example.study.DesignPattern.原型模式.Student
class com.example.study.DesignPattern.原型模式.Student
true
true
可见student1 ,student2 ,student3 具有相同的封装数据, student1 ,student2指向的堆区的同一个对象,student3确实是另一个对象,但是student1 和 student3 的score属性指向却是相同的对象,即Object支持的clone方式默认是浅拷贝,即只复制基本数据类,对于引用数据类型指向的还是相同的地址。
原型模式用于复制克隆一个新对象,而 == 却只是创建了一个临时变量指向了同一个对象。在修改复制的备份的数据时,不会对原型数据产生影响。