首页 > 其他 > 详细

原始模型模式

时间:2015-08-11 07:16:19      阅读:199      评论:0      收藏:0      [点我收藏+]

原始模型模式属于对象的创建模式。通过给出一个原始对象来致命所要创建的对象的类型,然后用复制这个原始对象的办法来创建出更多同类型的对象。

从孙大圣的手段谈起:悟空可以用猴毛根据自己的形象,复制出很多“身外之身”来。老孙的这种手段在面向对象的设计领域里叫做原始模型模式。

下面看一下,实现大圣自我复制的浅拷贝代码实现,代码包含三个类。一个齐天大圣类,其中包含一个本尊对象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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!