原型模式

什么是原型模式:

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

说白了,就是对象的克隆。克隆又分为浅克隆和深克隆。

浅克隆:只负责克隆按值传递的数据(比如基本数据类型、String类型),而不复制它所引用的对象,换言之,所有的对其他对象的引用都仍然指向原来的对象。

深克隆:除了浅度克隆要克隆的值外,还负责克隆引用类型的数据。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深度克隆把要复制的对象所引用的对象都复制了一遍,而这种对被引用到的对象的复制叫做间接复制。

  深度克隆要深入到多少层,是一个不易确定的问题。在决定以深度克隆的方式复制一个对象的时候,必须决定对间接复制的对象时采取浅度克隆还是继续采用深度克隆。因此,在采取深度克隆时,需要决定多深才算深。此外,在深度克隆的过程中,很可能会出现循环引用的问题,必须小心处理。

角色:

这种形式涉及到三个角色:

(1)客户(Client)角色:客户类提出创建对象的请求。

(2)抽象原型(Prototype)角色:这是一个抽象角色,通常由一个Java接口或Java抽象类实现。此角色给出所有的具体原型类所需的接口。

(3)具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。


案例:

1.具体原型:悟空角色和金箍棒

public class Wukong extends Prototype {
	private static final long serialVersionUID = 1L;
	private float weight;
	private int year;
	private GoldenCudgel goldenCudgel;

	public GoldenCudgel getGoldenCudgel() {
		return goldenCudgel;
	}

	public void setGoldenCudgel(GoldenCudgel goldenCudgel) {
		this.goldenCudgel = goldenCudgel;
	}

	public float getWeight() {
		return weight;
	}

	public void setWeight(float weight) {
		this.weight = weight;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}
}

public class GoldenCudgel implements Serializable {

	private static final long serialVersionUID = 1L;
	private float height = 10;
	private float wight = 0.1f;

	public float getHeight() {
		return height;
	}

	public void setHeight(float height) {
		this.height = height;
	}

	public float getWight() {
		return wight;
	}

	public void setWight(float wight) {
		this.wight = wight;
	}

}

2. 抽象原型(Prototype)角色

public abstract class Prototype implements Cloneable, Serializable {

	private static final long serialVersionUID = 1L;

	/**
	 * 深克隆
	 * 
	 * @return
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public Object deepClone() throws IOException, ClassNotFoundException {
		// 将对象写到流里
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(bos);
		oos.writeObject(this);
		// 从流里读回来
		ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bis);
		return ois.readObject();
	}

	/*
	 * 浅克隆
	 * @see java.lang.Object#clone()
	 */
	@Override
	protected Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
}

3. 客户(Client)角色,这里直接以测试类作为客户,复制角色

public class MainTest {

	public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {

		Wukong wukong1 = new Wukong();
		wukong1.setYear(10000);
		wukong1.setWeight(100f);
		GoldenCudgel goldenCudgel = new GoldenCudgel();
		wukong1.setGoldenCudgel(goldenCudgel);

		// 浅克隆
		Wukong wukong2 = (Wukong) wukong1.clone();
		System.out.println("浅克隆后对象是否是一样:" + (wukong1 == wukong2));
		System.out.println("浅克隆后,金箍棒是否一样:"
				+ (wukong1.getGoldenCudgel() == wukong2.getGoldenCudgel()));

		// 深度克隆
		Wukong wukong3 = (Wukong) wukong1.deepClone();
		System.out.println("深度克隆后对象是否是一样:" + (wukong1 == wukong3));
		System.out.println("深度克隆后,金箍棒是否一样:"
				+ (wukong1.getGoldenCudgel() == wukong3.getGoldenCudgel()));

	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值