java教程:关于Java设计模式关于原型模式(Prototype)

首先需要弄清楚什么叫原型模式,或者说为什么要有原型模式,运用它会给我们带来什么或能解决什么问题?原型模式(Prototype)同抽象工厂模式同属于创建型模式,它主要关注于大量相同或相似对象的创建问题,应用原型模式就是先需要一个原对象,然后通过对原对象进行复制(克隆),来产生一个与原对象相同或相似的新对象。注意这里所说的对象相同不是指复制出来的副本对象与原对象是同一个对象,相反复制出来的副本对象必须和原对象是两个不同的对象,只是两个对象的内容相同。
我们在编程过程中,经常会遇到这种情况,需要把一个对象的值赋值到另一个新对象,而且以后对新对象属性的修改不会影响到原对象,即两个对象是相互独立的,比如:
public clalss A{
private Long id;
private String name;
get set略......
public A(){}
public A(Long id,String name){
this.id = id;
this.name = name;
}
}
A a = new A(1,"a");
A b = null;
如果现在需要把对象a的内容全部复制到对象b中去,怎么办?如果你这样写,b = a;那就大错特错了,因为这样根据没有创建新对象,两个都是指向内存中同一个地址。或许你又会这样,b = new A(); 然后b.setId();
b.setName();这样一个一个的赋值。这样是创建了两个独立对象,但是还是有问题,如果对象属性有N多个怎么办,理论上这种情况是存在的,如果还是那样做,岂不是很累?怎么办?运用原型模式呗。实现原型模式很简单,只要待复制对象实现Cloneable接口,并重写父类Object的clone()方法即可。下面是我写的一个示例:
package com.prototype;
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;
/**
* 汤匙基类
*
* @author Lanxiaowei
* @createTime 2011-10-10 09:04
*/
public abstract class Spoon implements Cloneable,Serializable {
/**
* 名称
*/
private String name;
/**
* 价格
*/
private double price;
/**
* 使用人
*/
private People people;
public People getPeople() {
return people;
}
public void setPeople(People people) {
this.people = people;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Spoon() {
}
public Spoon(String name, double price) {
this.name = name;
this.price = price;
}
public Spoon(String name, double price,People people) {
this.name = name;
this.price = price;
this.people = people;
}
@Override
/**
* 浅复制
*/
protected Object clone() {
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException("Spoon is not Cloneable!");
}
return object;
}
/**
* 深度复制(推荐使用序列化的方式)
* @return
*/
protected Object deepClone() {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
Object object = null;
try {
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
object = oi.readObject();
} catch (OptionalDataException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return object;
}
/**
* 因为对于引用类型对象默认都是继承自Object类,
* 而Object类的equals()默认实现就是比较两者的内存地址引用,
* 所以需要重写equals()和hashCode()
* 至于为什么重写equals()还要重写hashCode(),那是sun的推荐做法
* (因为当对象作为散列key时用到key的hashCode,
* 而sun又规定两个对象若equals()为true,则hashCode()返回结果也应该相等)
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) 0 : name.hashCode());
long temp;
temp = Double.doubleToLongBits(price);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Spoon other = (Spoon) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (