<六>读<<大话设计模式>>之原型模式

 

        原型模式也是很简单的一种模式,对于java来说已经有相应的接口了(Cloneable)。关于原型模式<<大话设计模式>>是以投放简历作为例子讲解的,即我要投放很多简历,其实每个简历都一样,所以只要我写好一份,其他的复制就行了,其实就是今天讲的原型模式,就是把要复制的类对象的属性复制到另外一个对象上(其实不是复制而是对象的引用改变)。

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

浅复制VS深复制

关于克隆有两个概念

浅复制:就是只复制值类型的字段,不能复制引用的对象。意思就是简历类中引用了其他的对象的话,这个引用对象的数据是不会复制的。

深复制:不进复制值类型的字段,还复制引用的对象。区别浅复制不复制引用对象,深复制复制引用对象。

让我们通过代码来更好的理解它们吧

浅复制代码

1、工作经历类(即将被简历类所引用)

/*

 * 工作经历

 */

publicclass WorkExperienceSimple {

 

    private StringtimeArea;

 

    public String getTimeArea() {

       returntimeArea;

    }

 

    publicvoid setTimeArea(String timeArea) {

       this.timeArea = timeArea;

    }

}

2、简历类(关键是实现了Cloneable接口)

/*

 * 克隆中的浅复制代码

 */

 

publicclass ResumeSimpleimplements Cloneable {

 

    private Stringname;

    //private String timeArea;

   

    public WorkExperienceSimpletimeArea;

   

    public ResumeSimple(String name){

       this.name = name;

       timeArea =new WorkExperienceSimple();

    }

   

    publicvoid setWorkExperience(String workName){

       timeArea.setTimeArea(workName);

    }

   

    publicvoid display(){

       System.out.println("简历名称:"+name);

       System.out.println("工作地址:"+timeArea.getTimeArea());

    }

   

    @Override

    public Object clone()throws CloneNotSupportedException {

       ResumeSimpleo = null

       try

           o = (ResumeSimple) super.clone(); 

       } catch (CloneNotSupportedException e) { 

           e.printStackTrace(); 

       

       return o; 

    }

}

3、客户端

publicclass PrototypeClient {

 

    /**

     * @param args

     */

    publicstaticvoid main(String[] args) {

       //TODO Auto-generated method stub

 

       //浅复制

       System.out.println("--------浅复制开始----------");

       ResumeSimpleresumeSimple =new ResumeSimple("大鸟");

       resumeSimple.setWorkExperience("北京");

      

       //克隆1,完美呈现

       ResumeSimpleresumeSimple2;

       try {

           resumeSimple2= (ResumeSimple) resumeSimple.clone();

           resumeSimple2.setWorkExperience("上海");

          

           resumeSimple.display();

           resumeSimple2.display();

       }catch (CloneNotSupportedException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       }

      

    }

 

}

打印结果:

--------浅复制开始----------

简历名称:大鸟

工作地址:上海

简历名称:大鸟

工作地址:上海

看到了吧,工作经历都变成了上海,原来的北京没有被复制过来。这就是工作经历类没有被复制。

 

深复制

1、工作经历类(注意与浅复制区别)

/*

 * 工作经历

 * 与浅复制的区别1、实现了Cloneable接口2、实现接口的方法clone

 */

publicclassWorkExperienceDeepimplements Cloneable{

 

    private StringtimeArea;

 

    public String getTimeArea() {

       returntimeArea;

    }

 

    publicvoid setTimeArea(String timeArea) {

       this.timeArea = timeArea;

    }

   

    @Override

    public Object clone()throws CloneNotSupportedException {

       WorkExperienceDeep o =null

       try

           o = (WorkExperienceDeep)super.clone(); 

       } catch (CloneNotSupportedException e) { 

           e.printStackTrace(); 

       

       return o; 

    }

}

2、简历类(注意区别之处)

/*

 * 克隆中的浅复制代码

 * 与浅复制区别1、改变工作经历类的初始化方式,即增加构造函数ResumeDeep(WorkExperienceDeepworkName)

 * 2、

 */

 

public class ResumeDeepimplements Cloneable {

 

    private String name;

    //private String timeArea;

   

    public WorkExperienceDeep timeArea;

   

    public ResumeDeep(String name){

       this.name = name;

       timeArea = new WorkExperienceDeep();

    }

   

    public ResumeDeep(WorkExperienceDeep workName){

       try {

           timeArea = (WorkExperienceDeep) workName.clone();

       } catch (CloneNotSupportedException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

       }

    }

   

    public void setWorkExperience(String workName){

       timeArea.setTimeArea(workName);

    }

   

    public void display(){

       System.out.println("简历名称:"+name);

       System.out.println("工作地址:"+timeArea.getTimeArea());

    }

   

    @Override

    public Object clone(){

       ResumeDeep o = new ResumeDeep(this.timeArea);  //目的对工作经历进行深复制

        o.setName(name);

        return o; 

    }

 

    public void setName(String name) {

       this.name = name;

    }

}

3、客户端

publicclass PrototypeClient {

 

    /**

     * @param args

     */

    publicstaticvoid main(String[] args) {

       //TODO Auto-generated method stub

 

       //浅复制

       System.out.println("--------浅复制开始----------");

       ResumeSimpleresumeSimple =new ResumeSimple("大鸟");

       resumeSimple.setWorkExperience("北京");

      

       //克隆1,完美呈现

       ResumeSimpleresumeSimple2;

       try {

           resumeSimple2= (ResumeSimple) resumeSimple.clone();

           resumeSimple2.setWorkExperience("上海");

          

           resumeSimple.display();

           resumeSimple2.display();

       }catch (CloneNotSupportedException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       }

      

       //深复制

       System.out.println("--------深复制开始----------");

       ResumeDeepresumeDeep = new ResumeDeep("大鸟");

       resumeDeep.setWorkExperience("北京");

      

       //克隆1,完美呈现

       ResumeDeepresumeDeep2;

       resumeDeep2= (ResumeDeep) resumeDeep.clone();

       resumeDeep2.setWorkExperience("上海");

      

       resumeDeep.display();

       resumeDeep2.display();

      

    }

 

}

打印结果:

--------浅复制开始----------

简历名称:大鸟

工作地址:上海

简历名称:大鸟

工作地址:上海

--------深复制开始----------

简历名称:大鸟

工作地址:北京

简历名称:大鸟

工作地址:上海

 

很明显深复制把工作经历类也复制了过来,所以原来的北京值没有变化。

 

附上原型模式结构图:

<六>读<<大话设计模式>>之原型模式_第1张图片

总结:浅复制对于值类型没有问题,对于引用类型,就只是复制了引用,对引用的对象还是只向了原来的对象,所以会出现两个引用设置的“工作经历”,但是都是应用的最后的那个设置值,因为两个引用指向了同一个对象。但我们可能需要这样一种需求,把要复制的对象所引用的对象都复制一遍,那么我们就可以选择深复制的方式了。

 

附上代码:http://download.csdn.net/detail/jzhf2012/8102153

你可能感兴趣的:(java,设计模式,原型模式)