设计模式之Pototype

xiaoxiao2026-08-10  31

在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("!="); } }}
转载请注明原文地址: https://www.6miu.com/read-5051008.html

最新回复(0)