原型模式
原型(Prototype)模式的定義如下:用一個已經創建的實體作為原型,通過復制該原型物件來創建一個和原型相同或相似的新物件,
優點:當創建新的物件實體較為復雜時,使用原型模式可以簡化物件的創建程序,通過復制一個已有實體可以提高新實體的創建效率,
實作:原型模式的核心是重寫Object類中clone方法,通過該方法進行物件的拷貝,Java中提供了一個Cloneable介面來標示該物件是可拷貝的,它的作用是在運行時通知虛擬機可以安全地在實作了此介面的類上使用clone方法,如果沒有實作Cloneable介面,在運行時會拋出CloneNotSupportedException例外,
uml圖:

原型模式分為深拷貝和淺拷貝,
在Java語言中,資料型別分為值型別(基本資料型別)和參考型別,值型別包括int、double、byte、boolean、char等簡單資料型別,參考型別包括類、介面、陣列等復雜型別,淺克隆和深克隆的主要區別在于是否支持參考型別的成員變數的復制,
在淺拷貝中,如果原型物件的成員變數是值型別,將復制一份給克隆物件;如果原型物件的成員變數是參考型別,則將參考物件的地址復制一份給克隆物件,也就是說原型物件和克隆物件的成員變數指向相同的記憶體地址,簡單來說,在淺拷貝中,當物件被復制時只復制它本身和其中包含的值型別的成員變數,而參考型別的成員物件并沒有復制,
/**
* @author chen
*/
public class StudentPrototype implements Cloneable {
String name="";
String schoolName="";
TeacherPrototype teacherPrototype;
@Override
public StudentPrototype clone(){
StudentPrototype prototype = null;
try {
prototype = (StudentPrototype)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return prototype;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public TeacherPrototype getTeacherPrototype() {
return teacherPrototype;
}
public void setTeacherPrototype(TeacherPrototype teacherPrototype) {
this.teacherPrototype = teacherPrototype;
}
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
}
public class TeacherPrototype {
String name="";
@Override
public TeacherPrototype clone(){
TeacherPrototype prototype = null;
try {
prototype = (TeacherPrototype)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return prototype;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class StudentTest {
public static void main(String[] args) {
StudentPrototype studentPrototype1=new StudentPrototype();
TeacherPrototype teacherPrototype=new TeacherPrototype();
studentPrototype1.setName("張三");
studentPrototype1.setSchoolName("四中");
teacherPrototype.setName("張三的老師");
studentPrototype1.setTeacherPrototype(teacherPrototype);
StudentPrototype studentPrototype2=studentPrototype1.clone();
studentPrototype2.setName("李四");
studentPrototype2.getTeacherPrototype().setName("李四的老師");
System.out.println("學校:"+studentPrototype1.getSchoolName()+",,,學生:"+studentPrototype1.getName()+",,,老師:"+studentPrototype1.getTeacherPrototype().getName());
System.out.println("學校:"+studentPrototype2.getSchoolName()+",,,學生:"+studentPrototype2.getName()+",,,老師:"+studentPrototype2.getTeacherPrototype().getName());
}
}
輸出:
學校:四中,,,學生:張三,,,老師:李四的老師
學校:四中,,,學生:李四,,,老師:李四的老師
我們在給學生“李四”修改老師時,學生“張三”的老師也被修改了,
在深拷貝中,無論原型物件的成員變數是值型別還是參考型別,都將復制一份給克隆物件,深拷貝將原型物件的所有參考物件也復制一份給克隆物件,簡單來說,在深拷貝中,除了物件本身被復制外,物件所包含的所有成員變數也將復制,
/**
* @author chen
*/
public class StudentPrototype implements Cloneable {
private String name="";
private String schoolName="";
private TeacherPrototype teacherPrototype;
@Override
public StudentPrototype clone(){
StudentPrototype prototype = null;
try {
prototype = (StudentPrototype)super.clone();
TeacherPrototype teacherPrototype=this.teacherPrototype.clone();
prototype.setTeacherPrototype(teacherPrototype);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return prototype;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public TeacherPrototype getTeacherPrototype() {
return teacherPrototype;
}
public void setTeacherPrototype(TeacherPrototype teacherPrototype) {
this.teacherPrototype = teacherPrototype;
}
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
}
public class TeacherPrototype implements Cloneable{
private String name="";
@Override
public TeacherPrototype clone(){
TeacherPrototype prototype = null;
try {
prototype = (TeacherPrototype)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return prototype;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class StudentTest {
public static void main(String[] args) {
StudentPrototype studentPrototype1=new StudentPrototype();
TeacherPrototype teacherPrototype=new TeacherPrototype();
studentPrototype1.setName("張三");
studentPrototype1.setSchoolName("四中");
teacherPrototype.setName("張三的老師");
studentPrototype1.setTeacherPrototype(teacherPrototype);
StudentPrototype studentPrototype2=studentPrototype1.clone();
studentPrototype2.setName("李四");
studentPrototype2.getTeacherPrototype().setName("李四的老師");
System.out.println("學校:"+studentPrototype1.getSchoolName()+",,,學生:"+studentPrototype1.getName()+",,,老師:"+studentPrototype1.getTeacherPrototype().getName());
System.out.println("學校:"+studentPrototype2.getSchoolName()+",,,學生:"+studentPrototype2.getName()+",,,老師:"+studentPrototype2.getTeacherPrototype().getName());
}
}
輸出:
學校:四中,,,學生:張三,,,老師:張三的老師
學校:四中,,,學生:李四,,,老師:李四的老師
這樣對學生李四的老師賦值時不會改變學生李三老師的值,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/234875.html
標籤:java
上一篇:第一個Java程式
