《大話設計模式》Java程式碼示例(六)之原型模式
阿新 • • 發佈:2018-12-18
原型模式(Prototype):用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。
一、淺拷貝:被複制物件的所有變數都含有與原來物件相同的值,而所有的對其他物件的引用都仍然指向原來的物件。
package prototype.bitwisecopy; /** * 原型模式(Prototype):淺拷貝 * 工作經歷類 */ public class WorkExperience { private String workDate; private String company; public String getWorkDate() { return workDate; } public void setWorkDate(String workDate) { this.workDate = workDate; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } }
package prototype.bitwisecopy; /** * 原型模式(Prototype):淺拷貝 * 簡歷類 */ public class Resume implements Cloneable { private String name; private String sex; private String age; private WorkExperience workExperience; public Resume(String name) { this.name = name; workExperience = new WorkExperience(); } // 設定個人資訊 public void setPersonalInfo(String sex, String age) { this.sex = sex; this.age = age; } // 設定工作經歷 public void setWorkExperience(String workDate, String company) { workExperience.setWorkDate(workDate); workExperience.setCompany(company); } // 顯示 public void display() { System.out.println("姓名:" + name + ",性別:" + sex + ",年齡:" + age); System.out.println("工作經歷:" + workExperience.getWorkDate() + "," + workExperience.getCompany()); } @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } }
package prototype.bitwisecopy; /** * 原型模式(Prototype):淺拷貝 * 客戶端main方法 */ public class Client { public static void main(String[] args) throws CloneNotSupportedException { System.out.println("<-- 淺拷貝 -->"); Resume r0 = new Resume("大鳥"); r0.setPersonalInfo("男", "29"); r0.setWorkExperience("1998-2000", "xx公司"); Resume r1 = (Resume) r0.clone(); r1.setWorkExperience("1998-2006", "yy企業"); Resume r2 = (Resume) r0.clone(); r2.setPersonalInfo("女", "18"); r2.setWorkExperience("1998-2003", "zz企業"); // 淺拷貝中工作經歷的顯示結果都是最後一次設定的值 r0.display(); r1.display(); r2.display(); } }
輸出結果:
<-- 淺拷貝 -->
姓名:大鳥,性別:男,年齡:29
工作經歷:1998-2003,zz企業
姓名:大鳥,性別:男,年齡:29
工作經歷:1998-2003,zz企業
姓名:大鳥,性別:女,年齡:18
工作經歷:1998-2003,zz企業
二、深拷貝:把引用物件的變數指向複製過的新物件,而不是原有的被引用的物件。
package prototype.memberwisecopy;
/**
* 原型模式(Prototype):深拷貝
* 工作經歷類
*/
public class WorkExperience implements Cloneable {
private String workDate;
private String company;
public String getWorkDate() {
return workDate;
}
public void setWorkDate(String workDate) {
this.workDate = workDate;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package prototype.memberwisecopy;
/**
* 原型模式(Prototype):深拷貝
* 簡歷類
*/
public class Resume implements Cloneable {
private String name;
private String sex;
private String age;
private WorkExperience workExperience;
public Resume(String name) {
this.name = name;
this.workExperience = new WorkExperience();
}
public Resume(WorkExperience workExperience) throws CloneNotSupportedException {
this.workExperience = (WorkExperience) workExperience.clone();
}
// 設定個人資訊
public void setPersonalInfo(String sex, String age) {
this.sex = sex;
this.age = age;
}
// 設定工作經歷
public void setWorkExperience(String workDate, String company) {
workExperience.setWorkDate(workDate);
workExperience.setCompany(company);
}
// 顯示
public void display() {
System.out.println("姓名:" + name + ",性別:" + sex + ",年齡:" + age);
System.out.println("工作經歷:" + workExperience.getWorkDate() + "," + workExperience.getCompany());
}
@Override
public Object clone() throws CloneNotSupportedException {
Resume resume = new Resume(this.workExperience);
resume.name = this.name;
resume.sex = this.sex;
resume.age = this.age;
return resume;
}
}
package prototype.memberwisecopy;
/**
* 原型模式(Prototype):深拷貝
* 客戶端main方法
*/
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
System.out.println("<-- 深拷貝 -->");
Resume r0 = new Resume("大鳥");
r0.setPersonalInfo("男", "29");
r0.setWorkExperience("1998-2000", "xx公司");
Resume r1 = (Resume) r0.clone();
r1.setWorkExperience("1998-2006", "yy企業");
Resume r2 = (Resume) r0.clone();
r2.setPersonalInfo("女", "18");
r2.setWorkExperience("1998-2003", "zz企業");
// 深拷貝中工作經歷的顯示結果各不相同
r0.display();
r1.display();
r2.display();
}
}
輸出結果:
<-- 深拷貝 -->
姓名:大鳥,性別:男,年齡:29
工作經歷:1998-2000,xx公司
姓名:大鳥,性別:男,年齡:29
工作經歷:1998-2006,yy企業
姓名:大鳥,性別:女,年齡:18
工作經歷:1998-2003,zz企業