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

原型模式也是很简单的一种模式,对于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();

}

}

打印结果:

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

简历名称:大鸟

工作地址:上海

简历名称:大鸟

工作地址:上海

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

简历名称:大鸟

工作地址:北京

简历名称:大鸟

工作地址:上海

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

附上原型模式结构图:

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

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

时间: 2024-08-18 11:46:29

<六>读<<大话设计模式>>之原型模式的相关文章

大话设计模式_原型模式(Java代码)

原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 简单描述:即通过实现接口Cloneable重写方法clone(),使得创建新的拷贝对象不需要一个成员一个成员的重新复制,而且可以提高创建对象的效率 Java中要想实现拷贝使用clone()方法,类必须实现Cloneable接口,并且重写Object类中的clone()方法,调用父类的clone()方法即可实现浅复制 代码如下: WorkExperience类: 1 package com.longsheng.prototy

大话设计模式之原型模式

原型模式 定义: 用原型实例制定创建对象的种类,并通过拷贝这些原型,创建新的对象. 实质: 就是从一个对象在创建另一个可定制的对象,而且不需要知道任何创建的细节. 核心: (1).实现Cloneable接口,可以使用此接口的类上使用clone方法. (2).重写Object类中的clone方法,因为所有类的父类是Object类,Object有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此,将clone改为public类型. 结构图: 代

&lt;二&gt;读&lt;&lt;大话设计模式&gt;&gt;之策略模式

又和大家见面了,能够坚持写出第二篇文章真不错,好好加油. <<大话设计模式>>讲解策略模式是以商场收银软件程序开头的,那么问题来了,哪家商场收银软件强,开玩笑了.读过上篇文章<<简单工厂模式>>的知道,它有两个缺点:1.客户端依赖两个类,耦合性高:2.如果算法过多则需要写很多类.解决上面问题的就是策略模式了. 策略模式:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 商场收银软件:单价*打折算法=售价.

&lt;九&gt;读&lt;&lt;大话设计模式&gt;&gt;之建造者模式

学习了这么多模式,其实回想一下其实也没什么,就是用不同的方式设计代码,保证代码的可扩展性.复用等,稍微对代码进行一下修改就是另外一种模式.在我们工作中其实已经用了很多模式了,只不过不知道或者没留意他叫什么而已,无所谓,只要会用一切都是浮云. 关于<<大话设计模式>>对建造者模式的讲解是以画一个人来作为例子讲解的.人分为高人.矮人.胖人.瘦人等,但都是人,但当你去画一个人的时候,画的过程都是稳定的,都需要画头.身子.手.脚,不同的是建造的细节是不一样的.所以如果你需要将一个复杂的构件

&lt;八&gt;读&lt;&lt;大话设计模式&gt;&gt;之外观模式

外观模式其实很好理解的,就是将表面的东西展示给人看,内部的东西你不知道的(因为已经封装好了),比如一个外部系统要和公司内部5个系统进行交互,而这5个系统之间也有交互,那么第一种就是外部系统和5个系统都进行交互:第二种就是做一个接口将外部系统需要的逻辑封装成一个方法,该方法中包含了关于5个系统的交互方式,这样外部系统就不用直接和5个系统交互了,直接调用接口完事.外观模式也叫门面模式,其实说白了就是把要用的东西封装起来使交互更加方便. 外观模式定义:为子系统中的一组接口提供一个一致的界面,此模式定义

&lt;四&gt;读&lt;&lt;大话设计模式&gt;&gt;之代理模式

代理模式我想大家即便不熟悉也都听过吧,从字面意思上看就是替别人干活的,比如代理商.在项目的实际应用中也有很多地方用到,比如spring通过代理模式生成对象等. 代理模式的书面定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 在<<大话设计模式>>一书中以一个有男朋友的女孩让"小菜"帮忙修电脑的故事展开的,其实说白了代理就是帮别人干活的,一般老板不出面,

&lt;十二&gt;读&lt;&lt;大话设计模式&gt;&gt;之状态模式

对于状态模式,<<大话设计模式>>是以人从上班到下班到加班的状态来展开讲述的.状态模式其实就是某一个对象在某个过程或者时间的一个状态记录,但是这个状态的顺序不能发生变化,在程序设计方面可能要比其他模式稍微复杂点,请待我慢慢将来. 本人喜欢用代码来形象的讲述原理,可能是因为对单纯的看些理论的书有些反感或者无趣吧,我希望以后的教育也如此,要不大家都不高考了...嘿嘿说多了 状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 还是代码呈现吧,概念太抽象了.

大话设计模式笔记 原型模式

原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节. 基本类型与引用类型的区别于关系在efficient java. http://www.cnblogs.com/linkarl/p/4785329.html 浅复制:对象的引用仍然指向原来的对象 深复制:把引用对象的变量指向复制过的新对象 我认为一般深复制比较常用. package prototype; public

笔记-大话设计模式-09 原型模式

原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节. .NET在System命名空间中提供了ICloneable接口,其中就是唯一的一个方法Clone(),这样只需要实现这个接口就可以完成原型模式了.不用重新初始化对象,而是动态获得对象运行时的状态. 一般在初始化的信息不发生变化的情况下,克隆是最好的方法.这既隐藏了对象创建的细节,又对性能是大大的提高. 浅复制,被复