原始模型模式

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

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

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

从运行结果来看,大圣的金箍棒和身外之身的金箍棒也是不同的对象了,这是深拷贝的效果

时间: 2024-08-07 03:33:52

原始模型模式的相关文章

java设计模式--原始模型模式

简介 原始模型模式属于对象的创建模式.通过一个原型对象来指明要创建对象的类型,然后用复制原型对象的方法来创建出更多同类型的对象. Java所有的类都是从java.lang.Object类继承来的,Object类提供clone()方法对对象进行复制.一般调用clone()方法需要满足一下条件: 1.对于任何对象x,都有:x.clone()!=x.也就是克隆的对象和原对象不是一个对象. 2.对于任何对象x,都有:x.clone().getClass()=x.getClass().也就是克隆对象与原对

有趣的模式见解

创建型模式 1.FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了.麦当劳和肯德基就是生产鸡翅的Factory 工厂模式:客户类和工厂类分开.消费者任何时候需要某种产品,只需向工厂请求即可.消费者无须修改就可以接纳新产品.缺点是当产品修改时,工厂类也要做相应的修改.如:如何创建及如何向客户端提供. 2.BUILDER—MM最爱听的就是“我爱你”这句话了,见到不同地方的MM,要能够

Java经典23种设计模式之创造型模式(二)

本文记录5种创造型模式的剩下两种:建造者模式(Builder).原型模式(PROTOTYPE). 一.建造者模式(别名:生成者模式) 将复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示.一个完整的建造者模式包含以下几个概念: 1.产品类 Product public class Person { private String head; private String body; private String foot; public String getHead() { ret

原始(prototype)模型模式之简单形式与登记形式

原始模型模式有两种表现形式:第一种是简单形式,第二种是登记形式,下面将分别讲解两种原型模型模式的不同实现. 简单形式的原始模型模式 uml类图为: 这种形式涉及到三种角色: *客户(Client)角色:客户类提出创建对象的请求. *抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或者java抽象类实现. *具体原型(Concrete Prototype)角色:被复制的对象. 以下是一个简单的原型模型的实现. Client: package prototype.prot

Java 设计模式——原型模式(Prototype)

原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象. 原型模式有简单形式和登机形式两种表现 形式. 简单形式的原始模型模式 简单形式UML类图如下: 原型模式的角色有 客户端角色(ClientPro): 抽象原型角色(ProtoType): 具体原型角色(ConcreteProtoType):被复制的对象 代码如下: public interface ProtoType { /** * 根据自身克隆出新的对象 * @aut

Java常用的设计模式及工厂模式介绍

j2ee常用的设计模式?说明工厂模式. 总共23种,分为三大类:创建型,结构型,行为型 我只记得其中常用的6.7种,分别是: 创建型(工厂.工厂方法.抽象工厂.单例) 结构型(包装.适配器,组合,代理) 行为(观察者,模版,策略) 然后再针对你熟悉的模式谈谈你的理解即可. Java中的23种设计模式: Factory(工厂模式),      Builder(建造模式),       Factory Method(工厂方法模式), Prototype(原始模型模式),Singleton(单例模式)

4.泡妞与设计模式(五) 原型模式

PROTOTYPE 原型模式 原型模式允许动态的增加或减少产品类,产品类不需要非得有任何事先确定的等级结构,原始模型模式适用于任何的等级结构.缺点是每一个类都必须配备一个克隆方法.(简单点说就是调用的都可以找到原型,比如你和MM聊天,事先设计好一些情话,需要的时候copy就可以了,这时候情话就是原型) 原型模式:通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的方法创建出更多同类型的对象. 代码示例 1 #include <stdio.h> 2 #include <

java面试题大全

java面试笔试题大汇总     第一,谈谈final, finally, finalize的区别. 最常被问到. 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)? 第三,Static Nested Class 和 Inner Class的不同,说得越多越好(面试题有的很笼统). 第四,&和&&的区别. 这个问得很少. 第五,HashMap和Hashtable的区

转23种设计模式

1.FACTORY 追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说"来四个鸡翅"就行了.麦当劳和肯德基就是生产鸡翅的Factory 工厂模式:客户类和工厂类分开.消费者任何时候需要某种产品,只需向工厂请求即可.消费者无须修改就可以接纳新产品.缺点是当产品修改时,工厂类也要做相应的修改.如:如何创建及如何向客户端提供. 2.BUILDER MM最爱听的就是"我爱你"这句话了,见到不同