`
zhanghuifeng
  • 浏览: 10005 次
  • 性别: Icon_minigender_1
  • 来自: 江苏
最近访客 更多访客>>
社区版块
存档分类
最新评论

设计模式之Pototype

阅读更多
在java语言中,当我们在传递参数时,如是是个对象,我们并不想在在方法中改变对象的值,那么我们该怎么办:
1,可以new 一个对象,然后再setXXX(getXXX())来给对象赋值,如果要产生N个,比如N是100,如果这个对象有N个属性,比如10个,这样就要new100次,get,set 1000次。这样工作是相当无聊的,而且无意义。
2,采用Object的clone()方法,也就是复制对象,需实现Cloneable接口否则会抛出CloneNotSupportedException异常代码如下:
可是,如果当该对象的属性不是基本数据类型的是,如是某个对象,该对象的属性与原对象的属性是同一个,即引用指向同一个对象,在堆内存中并没有为该属性开辟一块新的内存。
为解决此问题,我们来谈谈,浅复制,和深复制。
⑴浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
如下java代码:
public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
⑵深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍,如下java代码:
public Object deepClone() throws IOException, OptionalDataException,
			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());
}
下面我给下有关代码及注释:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.io.Serializable;
/*
 * 1.使用Prototype模式的一个好处就是可以节省大量的接口实现类的编写。
 * 采用工厂模式的话,如果分别为用户指定的每种场合都提供一个用户接口
 * 工厂类,将会为我们带来繁重的工作量。未来避免用户接口工厂类不断增
 * 加,可以考虑使用Prototype模式。
 * 2.而Prototype模式的一个致命的缺点是:Java中的原型方法不允许新对
 * 象拥有与父对象不同的方法。这时候,在使用原型方法之前,需要仔细考
 * 虑原型方法的利弊,甚至要试一下Prototype模式是否满足需求。
 * 3.综上所述:Prototype模式最适用的场合应该是:当几个对象的类仅在
 * 属性上存在一点差异,而行为上完全相同时。可以在复制一个原型对象后,
 * 对其属性进行细小的微调,从而实现定制化的目的。
 * */
public class BookBean implements Cloneable,Serializable {
	private Integer id;
	private String name;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}
	/*
	 * 深克隆需要使用Java中提供的
	 * 对象串行化功能-即把要复制
	 * 的对象写入到一个缓冲流,然
	 * 后通过输入流读入,完成对象
	 * 的复制
	 * */
	public Object deepClone() throws IOException, OptionalDataException,
			ClassNotFoundException {
try {
			   // 在内存中开辟一块缓冲区,用于将自身写入
			   ByteArrayOutputStream bos = new ByteArrayOutputStream();
			   ObjectOutputStream out = new ObjectOutputStream(bos);
			   // 通过Serialization机制将自身写入缓冲区
			   out.writeObject(this);
			   out.close();
			   / /读
			   ByteArrayInputStream bis = new ByteArrayInputStream(bos
			     .toByteArray());
			   ObjectInputStream in = new ObjectInputStream(bis);
			   // 将刚才写入的内容读入一个新的对象
			    Object ret = in.readObject();
			   in.close();
			   // 返回对象
			   return ret;
			  } catch (Exception e) {
			   e.printStackTrace();
			   return null;
			  }
	}
}
下面是一个测试类:
public class TestPrototype {
	public static void main(String args[]) throws Exception{
		BookBean book=new BookBean();
		book.setId(1);
		book.setName("java设计模式");
		System.out.println(book.getId()+","+book.getName());
		BookBean book2=(BookBean)book.deepClone();
		System.out.println(book2.getId()+","+book2.getName());
		if(book==book2){
			System.out.println("==");
		} else {
			System.out.println("!=");
		}
		if(book.getId()==book2.getId()){
			System.out.println("==");
		}else {
			System.out.println("!=");
		}
		if(book.getName()==book2.getName()){
			System.out.println("==");
		}else {
			System.out.println("!=");
		}
		
	}
}
分享到:
评论
1 楼 zhuzhuzhumop 2009-05-31  
楼主非常强悍!第一次离楼主这么近

相关推荐

    设计模式之蝉

    《设计模式之蝉》这本书可能是对设计模式的一种形象化描述,或是以蝉为比喻来讲解设计模式的概念。蝉在地下蛰伏多年,最终破土而出,仅生活在地面上的几周时间。这一生命周期与设计模式的持久价值有异曲同工之妙,即...

    设计模式之美——教你写出高质量代码

    "设计模式之美——教你写出高质量代码"这个主题旨在帮助开发者更好地理解和应用设计模式,从而提升代码的质量和可维护性。设计模式不仅对面试有所帮助,也是职场发展中的必备技能,无论你使用哪种开发语言。 设计...

    设计模式之美—学习笔记

    在这个“设计模式之美”的学习笔记中,我们将探讨一些主要的设计模式,以及它们在实际开发中的应用。 首先,我们从创建型模式开始。这类模式主要用于对象的创建,如单例模式(Singleton)、工厂模式(Factory ...

    GOF设计模式中英文+设计模式精解中英文

    GOF(Gang of Four)设计模式,由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位专家在他们的著作《设计模式:可复用面向对象软件的基础》中提出,被誉为设计模式的经典之作。本资源包含了GOF设计...

    Java 经典设计模式讲解以及项目实战

    Java 经典设计模式讲解以及项目实战 设计模式简介:主要介绍各种设计模式的概念和运用场景等 设计模式综合运用:主要是笔者在实际工作中运用到的一些设计模式综合运用事例的提炼 Spring设计模式简介:主要是讲述...

    设计模式之我见

    ### 设计模式之我见 #### 设计模式的定义与意义 设计模式(Design Pattern)是一种在软件开发过程中被广泛采用的方法论,它基于一系列反复验证的解决方案,旨在提高代码的可读性、可重用性和可靠性。设计模式是...

    设计模式之我见源代码

    "设计模式之我见源代码"系列是作者分享的设计模式实践和理解,通过源代码的形式帮助读者深入理解和应用设计模式。 在提供的压缩包文件中,我们看到几个关键的目录和文件: 1. `.classpath`:这是一个Eclipse项目...

    C++设计新思维:泛型编程与设计模式之应用(PDF)

    《C++设计新思维:泛型编程与设计模式之应用》是一本深入探讨C++编程技术的著作,尤其强调了泛型编程和设计模式在实际软件开发中的应用。作者通过丰富的实例和深入的分析,引领读者理解并掌握C++的核心理念和高级...

    Head First设计模式.pdf

    全书用两章篇幅对设计模式和GRASP作了基本介绍,3种设计模式的讲解:对于每一种模式,先给出定义,接着通过类比方式用一个现实世界中的例子说明模式的应用,然后分别以C#和Java代码例述模式的架构实现。最后一章给出...

    软件设计模式期末作业

    在软件开发领域,设计模式是经过时间和实践验证的解决方案模板,用于解决常见问题。本作业以“软件设计模式”为主题,特别关注了装饰模式、工厂模式和适配器模式的运用。这三种模式都是面向对象设计的核心部分,它们...

    C++设计新思维:泛型编程与设计模式之应用.pdf 带目录书签

    C++设计新思维:泛型编程与设计模式之应用.pdf 带目录书签

    JavaScript设计模式.pdf

    单体模式是JavaScript中最基本的设计模式之一。它的主要作用是提供一个命名空间,减少全局变量的数量,避免代码冲突,并组织代码使其易于维护。单体模式可以用来划分命名空间,组织代码和避免代码冲突。 2. 工厂...

    软件设计模式--填空题+简答题(复习7).rar

    《软件设计模式--填空题+简答题(复习7).rar》这个压缩包文件是一个针对《软件设计模式与体系结构》课程的复习资料,重点涵盖了软件设计中的关键概念和实践。设计模式是软件工程中的一种最佳实践,它代表了在特定上...

    您的设计模式.pdf。

    本书《您的设计模式》对设计模式进行了详细的讲解,涵盖了策略模式、代理模式、单例模式、多例模式、工厂方法模式、抽象工厂模式、门面模式、适配器模式、模板方法模式、建造者模式、桥梁模式、命令模式、装饰模式、...

    23种设计模式(C++).pdf

    《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》是一本深入探讨软件设计模式的书籍,它涵盖了创建型、结构型和行为型三种主要类型的23个经典设计模式,并提供了C++语言的实现代码。设计模式是软件工程中的...

    设计模式期末作业(要求5个以上的设计模式的模拟系统)

    这是我的设计模式作业:运用5个以上的设计模式创建一个系统。其中包括:1.单例模式 2.原型模式 3.抽象工厂模式+模板方法模式 4.代理模式 5.策略模式 详见博文:...

    Head First设计模式(完整高清版).pdf

    《Head First设计模式》是一本深受开发者喜爱的经典书籍,它以独特且易于理解的方式介绍了设计模式这一复杂的概念。设计模式是软件开发中的经验总结,是解决常见问题的有效模板,可以帮助我们编写更灵活、可维护和可...

Global site tag (gtag.js) - Google Analytics