博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式梳理——原型模式
阅读量:4096 次
发布时间:2019-05-25

本文共 6487 字,大约阅读时间需要 21 分钟。

一、概述

       原型模式(ProtoType),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 

二、UML图示

三、编程实现

       该程序主要通过模拟复制简历的功能实现。

1、具体原型类

public class Resume implements Cloneable {    private String name;    private int age;    private String sex;    private String timeArea;    private String company;    public Resume(String name) {        this.name = name;    }    /**     * 设置个人信息     * @param sex     * @param age     */    public void setPersonInfo(String sex,int age){        this.sex = sex;        this.age = age;    }    /**     * 设置工作经历     * @param timeArea     * @param company     */    public void setWorkExperience(String timeArea,String company){        this.timeArea = timeArea;        this.company = company;    }    public void display(){        System.out.println(this.name + ","+this.sex+","+this.age);        System.out.println(this.timeArea+","+this.company);    }    public Object clone(){        Resume resume = null;        try {           resume =(Resume) super.clone();        }catch (CloneNotSupportedException e){            System.out.println(e);        }        return resume;    }}

2、测试类

public class Test {    public static void main(String[] args) {        Resume resume1 = new Resume("aa");        resume1.setPersonInfo("male",25);        resume1.setWorkExperience("2015-2018","xx公司");        Resume resume2 = (Resume) resume1.clone();        resume2.setWorkExperience("2015-2018","yy公司");        Resume resume3 = (Resume)resume1.clone();        resume3.setPersonInfo("female",29);        resume1.display();        resume2.display();        resume3.display();    }}输出:aa,male,252015-2018,xx公司aa,male,252015-2018,yy公司aa,female,292015-2018,xx公司

        在初始化信息不变的情况下,克隆是最好的办法。既隐藏了对象创建的细节,又大大提高了性能。

        存在问题:

               clone()方法中,如果字段是值类型,则对该字段进行逐位复制,如果该字段是引用类型,则复制引用但不复制

        引用的对象,因此原始对象及其副本引用同一对象。

四、浅复制编程问题

1、封装工作经历类

public class WorkExperience {    private String timeArea;    private String company;    public String getTimeArea() {        return timeArea;    }    public void setTimeArea(String timeArea) {        this.timeArea = timeArea;    }    public String getCompany() {        return company;    }    public void setCompany(String company) {        this.company = company;    }}

2、resume类修改

public class Resume implements Cloneable {    private String name;    private int age;    private String sex;    private WorkExperience workExperience;    public Resume(String name) {        this.name = name;        workExperience = new WorkExperience();    }    /**     * 设置个人信息     * @param sex     * @param age     */    public void setPersonInfo(String sex,int age){        this.sex = sex;        this.age = age;    }    /**     * 设置工作经历     * @param timeArea     * @param company     */    public void setWorkExperience(String timeArea,String company){        workExperience.setTimeArea(timeArea);;        workExperience.setCompany(company);    }    public void display(){        System.out.println(this.name + ","+this.sex+","+this.age);        System.out.println(workExperience.getTimeArea()+","+workExperience.getCompany());    }    public Object clone(){        Resume resume = null;        try {           resume =(Resume) super.clone();        }catch (CloneNotSupportedException e){            System.out.println(e);        }        return resume;    }}

3、测试类

public class Test {    public static void main(String[] args) {        Resume resume1 = new Resume("aa");        resume1.setPersonInfo("male",25);        resume1.setWorkExperience("2015-2018","xx公司");        Resume resume2 = (Resume) resume1.clone();        resume2.setWorkExperience("2015-2018","yy公司");        Resume resume3 = (Resume)resume1.clone();        resume3.setPersonInfo("female",29);        resume1.display();        resume2.display();        resume3.display();    }}输出:aa,male,252015-2018,yy公司aa,male,252015-2018,yy公司aa,female,292015-2018,yy公司

可以看出输出的都是yy公司,存在浅复制问题。

“浅复制”,即被复制对象所有变量都含有与原来对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。而“深复制”则可把引用对象的变量指向复制过的新对象,而不是原来对象。

五、深复制实现

1、工作经历类实现cloneable接口,并重写clone方法

public class WorkExperience implements Cloneable{    private String timeArea;    private String company;    public String getTimeArea() {        return timeArea;    }    public void setTimeArea(String timeArea) {        this.timeArea = timeArea;    }    public String getCompany() {        return company;    }    public void setCompany(String company) {        this.company = company;    }    public Object clone(){        WorkExperience workExperience = null;        try {            workExperience =(WorkExperience) super.clone();        }catch (CloneNotSupportedException e){            System.out.println(e);        }        return workExperience;    }}

2、简历类修改

public class Resume implements Cloneable {    private String name;    private int age;    private String sex;    private WorkExperience workExperience;    public Resume(String name) {        this.name = name;        this.workExperience = new WorkExperience();    }    private Resume(WorkExperience workExperience){        this.workExperience = (WorkExperience) workExperience.clone();    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    /**     * 设置个人信息     * @param sex     * @param age     */    public void setPersonInfo(String sex,int age){        this.sex = sex;        this.age = age;    }    /**     * 设置工作经历     * @param timeArea     * @param company     */    public void setWorkExperience(String timeArea,String company){        this.workExperience.setTimeArea(timeArea);;        this.workExperience.setCompany(company);    }    public void display(){        System.out.println(this.name + ","+this.sex+","+this.age);        System.out.println(workExperience.getTimeArea()+","+workExperience.getCompany());    }    public Object clone(){        Resume resume = new Resume(this.workExperience);        resume.setPersonInfo(this.sex,this.age);        resume.setName(this.name);        return resume;    }}

3、测试

public class Test {    public static void main(String[] args) {        Resume resume1 = new Resume("aa");        resume1.setPersonInfo("male",25);        resume1.setWorkExperience("2015-2018","xx公司");        Resume resume2 = (Resume) resume1.clone();        resume2.setWorkExperience("2015-2018","yy公司");        Resume resume3 = (Resume)resume1.clone();        resume3.setPersonInfo("female",29);        resume1.display();        resume2.display();        resume3.display();    }}输出:aa,male,252015-2018,xx公司aa,male,252015-2018,yy公司aa,female,292015-2018,xx公司

注:参考文献《大话设计模式》程杰著。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的文章
[JAVA学习笔记-88]DelayQueue实现Leader-Follower pattern
查看>>
[JAVA学习笔记-95]REST框架浅析
查看>>
[JAVA学习笔记-96]ThreadLocal
查看>>
[JAVA学习笔记-97]ActiveObject模式的Scheduler的关键实现
查看>>
【代码积累-1】ActiveObject
查看>>
【代码积累-2】binary search
查看>>
【代码积累-3】bubble sort
查看>>
【代码积累-4】cal MD5
查看>>
【代码积累】condition of lock
查看>>
【代码积累】countdown latch
查看>>
【代码积累】semaphore
查看>>
【代码积累】Date split
查看>>
【代码积累】Enum
查看>>
【代码积累】Event handling framrwork
查看>>
【代码积累】factory pattern without reflection
查看>>
【代码积累】FlexibleIterator
查看>>
【代码积累】ForkJoin sum the array
查看>>
【代码积累】FutureTask
查看>>
【代码积累】InsertionSort
查看>>
【代码积累】InsertionSort via list
查看>>