目錄
原型模式的使用案例
原型模式是創建型模式之一,使用原型模式創建對象比直接new對象的性能高、簡化創建過程。原型模式的使用較爲簡單,具體實現如下
public class Group implements Cloneable{
private String groupName;
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Group{" +
"groupName='" + groupName + '\'' +
'}';
}
}
public class Student implements Cloneable{
private Integer Id;
private Group group;
private String name;
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public Integer getId() {
return Id;
}
public void setId(Integer id) {
Id = id;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Student{" +
"Id=" + Id +
", group=" + group +
", name='" + name + '\'' +
'}';
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException {
Student jon = new Student();
for(int i = 0 ; i <5 ; i++){
Student studentClon = (Student) jon.clone();
studentClon.setId(i);
System.out.println(studentClon);
}
}
}
運行main方法,輸出結果符合我們的預期,這就是最簡單的原型模式實際運用。
Student{Id=0, group=null, name='null'}
Student{Id=1, group=null, name='null'}
Student{Id=2, group=null, name='null'}
Student{Id=3, group=null, name='null'}
Student{Id=4, group=null, name='null'}
操作複合對象出現的問題及解決方案
在操作複合對象時可能會出現一個數據錯誤,修改main方法並運行
public static void main(String[] args) throws CloneNotSupportedException {
Student jon = new Student();
jon.setName("jon");
Group group1 = new Group();
group1.setGroupName("A");
jon.setGroup(group1);
Student jonClone = (Student)jon.clone();
jonClone.setName("jonClone");
jonClone.getGroup().setGroupName("B");
System.out.println(jon.toString());
System.out.println(jonClone.toString());
}
預期輸出的結果應該是
Student{Id=null, group=Group{groupName='A'}, name='jon'}
Student{Id=null, group=Group{groupName='B'}, name='jonClone'}
但是實際運行結果卻是
Student{Id=null, group=Group{groupName='B'}, name='jon'}
Student{Id=null, group=Group{groupName='B'}, name='jonClone'}
可以看出,在修改jonClone的同時也修改了jon的group屬性,那爲什麼會這樣呢?對代碼進行debug
可以看到jon和jonClone的group屬性內存地址都是{Group@472},所以jon和jonClone的group是同一個對象。這就是淺克隆。 試想我們在實際工作中出現這樣的數據處理是多麼可怕,可能會造成重大事故。
解決方法是對克隆方法的複合屬性也進行克隆
@Override
protected Object clone() throws CloneNotSupportedException {
Student studen = (Student)super.clone();
studen.group =(Group)studen.group.clone();
return studen;
}
重新運行結果如下,數據符合預期。
Student{Id=null, group=Group{groupName='A'}, name='jon'}
Student{Id=null, group=Group{groupName='B'}, name='jonClone'}
對修改後的代碼進行debug,可以看出克隆前後的group對象不同,這是深克隆。
深克隆和淺克隆的區別
淺克隆:是指拷貝對象時僅僅拷貝對象本身(包括對象中的基本變量),而不拷貝對象包含的引用指向的對象。
深克隆:不僅拷貝對象本身,而且拷貝對象包含的引用指向的所有對象。
覺得不錯,請點個贊 (-__-)謝謝