1. 程式人生 > >《大話設計模式》Java程式碼示例(六)之原型模式

《大話設計模式》Java程式碼示例(六)之原型模式

原型模式(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企業