标签:
原始模型模式属于对象的创建模式。通过给出一个原始对象来致命所要创建的对象的类型,然后用复制这个原始对象的办法来创建出更多同类型的对象。
从孙大圣的手段谈起:悟空可以用猴毛根据自己的形象,复制出很多“身外之身”来。老孙的这种手段在面向对象的设计领域里叫做原始模型模式。
下面看一下,实现大圣自我复制的浅拷贝代码实现,代码包含三个类。一个齐天大圣类,其中包含一个本尊对象Monkey。还有一个Monkey类,用来定义悟空。还有一个金箍棒类,定义金箍棒。
import java.util.Date;
/*
* Monkey类,定义猴子
* */
public class Monkey implements Cloneable
{
private int height;
private int weight;
private GoldRingedStaff staff;
private Date birthDate;
public Monkey()
{
this.birthDate=new Date();
this.staff=new GoldRingedStaff();
}
/*
* 克隆方法
* */
public Object clone()
{
Monkey temp=null;
try {
temp=(Monkey)super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
System.err.println("clone failed");
}
return temp;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public GoldRingedStaff getStaff() {
return staff;
}
public void setStaff(GoldRingedStaff staff) {
this.staff = staff;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}
*
* 金箍棒类源代码
* */
public class GoldRingedStaff {
private float height=100.0F;
private float diameter=10.0F;
public GoldRingedStaff()
{
//write you code here
}
/*
* 增长行为,每次调用长度和半径增加一倍
* */
public void grow()
{
this.diameter*=2.0;
this.height*=2.0;
}
/*
* 缩小行为,每次调用长度和半径减少一半
* */
public void shrink()
{
this.diameter/=2.0;
this.height/=2.0;
}
/*
* 移动方法
* */
public void move()
{
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
public float getDiameter() {
return diameter;
}
public void setDiameter(float diameter) {
this.diameter = diameter;
}
}
public class TheGreatestSage {
//大圣本尊
private Monkey monkey=new Monkey();
public void change()
{
//大圣的克隆版
Monkey copyMonkey;
//空转一会,模拟克隆过程
for(int i=0;i<200;i++){}
//复制
copyMonkey=(Monkey)monkey.clone();
System.out.println("悟空本尊的生日:"+monkey.getBirthDate());
System.out.println("复制悟空的生日:"+copyMonkey.getBirthDate());
System.out.println("悟空本尊和复制悟空的生日是否是一个对象:"+(copyMonkey.getBirthDate()==monkey.getBirthDate()));
System.out.println("悟空本尊和复制悟空是否相同:"+(monkey==copyMonkey));
System.out.println("悟空本尊和复制悟空的金箍棒是否相同:"+(monkey.getStaff()==copyMonkey.getStaff()));
}
public static void main(String[] args) {
TheGreatestSage tgs=new TheGreatestSage();
tgs.change();
}
}
运行结果: 悟空本尊的生日:Tue Aug 11 03:02:07 CST 2015 复制悟空的生日:Tue Aug 11 03:02:07 CST 2015 悟空本尊和复制悟空的生日是否是一个对象:true 悟空本尊和复制悟空是否相同:false 悟空本尊和复制悟空的金箍棒是否相同:true
从运行结果可以看出,复制的悟空确实和大圣不是一个对象,他们具有同一个生日,金箍棒也是共享的,只有一个,因此浅拷贝不符合要求。需要用深拷贝来完成大圣的复制。
下面是深拷贝的实现,用序列化的方式实现深拷贝,则需要拷贝的类均需要实现Serializable接口,代码主要修改是给GoldRingedStaff实现Serializable接口,以及Monkey类也实现该接口同时添加deepCpoy()方法
/*
* 金箍棒类源代码
* */
public class GoldRingedStaff implements Serializable{
private float height=100.0F;
private float diameter=10.0F;
public GoldRingedStaff()
{
//write you code here
}
/*
* 增长行为,每次调用长度和半径增加一倍
* */
public void grow()
{
this.diameter*=2.0;
this.height*=2.0;
}
/*
* 缩小行为,每次调用长度和半径减少一半
* */
public void shrink()
{
this.diameter/=2.0;
this.height/=2.0;
}
/*
* 移动方法
* */
public void move()
{
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
public float getDiameter() {
return diameter;
}
public void setDiameter(float diameter) {
this.diameter = diameter;
}
}
/*
* Monkey类,定义猴子
* */
public class Monkey implements Cloneable,Serializable
{
private int height;
private int weight;
private GoldRingedStaff staff;
private Date birthDate;
public Monkey()
{
this.birthDate=new Date();
this.staff=new GoldRingedStaff();
}
/*
* 深拷贝方法
* */
public Object deepClone() throws IOException, ClassNotFoundException
{
//将对象写到流里
ByteArrayOutputStream bo=new ByteArrayOutputStream();
ObjectOutputStream oo=new ObjectOutputStream(bo);
oo.writeObject(this);
//将对象读出来
ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi=new ObjectInputStream(bi);
return oi.readObject();
}
/*
* 克隆方法
* */
public Object clone()
{
Monkey temp=null;
try {
temp=(Monkey)super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
System.err.println("clone failed");
}
return temp;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public GoldRingedStaff getStaff() {
return staff;
}
public void setStaff(GoldRingedStaff staff) {
this.staff = staff;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}
运行结果: 悟空本尊的生日:Tue Aug 11 03:06:09 CST 2015 复制悟空的生日:Tue Aug 11 03:06:09 CST 2015 悟空本尊和复制悟空的生日是否是一个对象:false 悟空本尊和复制悟空是否相同:false 悟空本尊和复制悟空的金箍棒是否相同:false
从运行结果来看,大圣的金箍棒和身外之身的金箍棒也是不同的对象了,这是深拷贝的效果
标签:
原文地址:http://www.cnblogs.com/xtsylc/p/4719793.html