国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > 互联网 > <六>读<<大话设计模式>>之原型模式

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

来源:程序员人生   发布时间:2014-11-14 08:18:07 阅读次数:3447次

 

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

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

浅复制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个对象。但我们可能需要这样1种需求,把要复制的对象所援用的对象都复制1遍,那末我们就能够选择深复制的方式了。

 

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

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生