当前位置:编程学习 > JAVA >>

浅谈Java设计模式关于原型模式(Prototype)思索建议

java教程:关于Java设计模式关于原型模式(Prototype)
java教程java设计模式
首先需要弄清楚什么叫原型模式,或者说为什么要有原型模式,运用它会给我们带来什么或能解决什么问题?原型模式(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 (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price))
return false;
return true;
}
}

 

package com.prototype;
/**
* 汤匙子类
* @author Lanxiaowei
* @createTime 2011-10-10 09:20
*/
public class SoupSpoon extends Spoon {
public SoupSpoon() {
super();
}

public SoupSpoon(String name,double price){
super(name,price);
}

public SoupSpoon(String name,double price,People people){
super(name,price,people);
}
}

 

 

package com.prototype;

import java.io.Serializable;

/**
* 使用人
*
* @author Lanxiaowei
* @createTime 2011-10-10 11:19
*/
public class People implements Serializable{
private String name;

public String getName() {
return name;
}

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

public People(){}

public People(String name){
this.name = name;
}
}

 

package com.prototype;
/**
* 测试类
*
* @author Lanxiaowei
* @createTime 2011-10-10 11:34
*/
public class Test {
public static void main(String[] args) {
/******************************************测试对象浅复制 begin************************************************/
//通过Cloneable接口浅复制一个新对象(注意Cloneable接口对于引用类型对象只能复制内存地址引用,即"浅复制")
Spoon spoon1 = new SoupSpoon("汤匙",20.5);
Spoon spoon2 = (SoupSpoon)spoon1.clone();

System.out.println("spoon1与spoon2相等吗?" + (spoon1.equals(spoon2)));
System.out.println("spoon1与spoon2是同一个对象吗?" + (spoon1 == spoon2));

System.out.println("");

//直接通过new关键字创建一个新对象
Spoon spoon3 = new SoupSpoon("汤匙",20.5);
Spoon spoon4 = new SoupSpoon("汤匙",20.5);

System.out.println("spoon3与spoon4相等吗?" + (spoon3.equals(spoon4)));
System.out.println("spoon3与spoon4是同一个对象吗?" + (spoon3 == spoon4));
/******************************************测试对象浅复制 end**************************************************/

System.out.println("");

/******************************************测试对象深复制 begin************************************************/
//通过deepClone()深复制对象
Spoon spoon5 = new SoupSpoon("汤匙",20.5,new People("zhangsan"));
Spoon spoon6 = (SoupSpoon)spoon5.deepClone();
System.out.println("spoon5与spoon6相等吗?" + (spoon5.equals(spoon6)));
System.out.println("spoon5与spoon6是同一个对象吗?" + (spoon5 == spoon6));补充:软件开发 , Java ,

CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,