设计模式之原型模式(Prototype)

    原型模式就是通过一个原有的原型对象来表明要创建对象的类型,然后通过复制这个原型对象来创建同类型的对象。  

   当我们在写一个应用的时候,假如有一个对象,并且这个对象包含了一些有效值,而我们需要和该对象完全相同的新对象来做其他操作,这时我们就可以使用Prototype模式了,通过复制原有的对象,然后在复制后的对象上进行所需操作。

我们要想实现原型模式,可以通过实现java的Cloneable接口,并复写他的clone()方法:

@Override
protected Object clone() throws CloneNotSupportedException {
        return super.clone();
}


Clone分为深度Clone和浅度Clone,如果我们克隆的对象中没有重载了clone()方法的引用类型,那么我们可以使用浅度克隆,如果有并且希望克隆对象中的引用类型也被克隆,那么我们就需要用到深度克隆了,接下来我们看一个例子:

我们有一个Dog类,他有一个legCount变量来表示腿的数量,还有一个DogClone类,来表示Dog的克隆类,并实现了Cloneable接口,复写了clone方法:

Dog类:

package com.dxy.design.pattern.prototype;

public class Dog {
	private int legCount;
	
	public Dog(int legCount) {
		this.legCount = legCount;
	}
	
	public void changeLegCount() {
		this.legCount *= 2;
	}

	@Override
	public String toString() {
		return Integer.toString(this.legCount);
	}
}


DogClone类:

package com.dxy.design.pattern.prototype;

public class DogClone implements Cloneable {
	
	private int legCount;
	
	private Dog dog = new Dog(4);

	@Override
	protected Object clone() throws CloneNotSupportedException {
		DogClone d = (DogClone)super.clone();
		return d;
	}

	public int getLegCount() {
		return legCount;
	}

	public void setLegCount(int legCount) {
		this.legCount = legCount;
	}

	public Dog getDog() {
		return dog;
	}

	public void setDog(Dog dog) {
		this.dog = dog;
	}
}

客户端类Client:

package com.dxy.design.pattern.prototype;

public class Client {
	public static void main(String[] args) throws Exception  {
		DogClone dogClone = new DogClone();
		dogClone.setLegCount(3);
		System.out.println("原克隆腿数量:"+dogClone.getLegCount());
		System.out.println("原腿数量:"+dogClone.getDog());
		
		DogClone dogClone1 = (DogClone)dogClone.clone();
		dogClone1.setLegCount(2);
		Dog dog = dogClone1.getDog();
		dog.changeLegCount();
		
		System.out.println("原克隆腿数量:"+dogClone.getLegCount());
		System.out.println("原腿数量:"+dogClone.getDog());
		System.out.println("克隆后克隆腿数量:"+dogClone1.getLegCount());
		System.out.println("克隆后腿数量:"+dogClone1.getDog());
	}
}

执行结果如图:

由执行结果我们可以看出,克隆后的Dog的legCount改变了,而我们需要的是对克隆对象进行操作对原对象无任何影响,这时我们就需要用到深度克隆了,深度克隆需要将克隆类中的引用类型进行克隆,所以Dog类也需要实现Cloneable接口并复写clone()方法:

package com.dxy.design.pattern.prototype;

public class Dog implements Cloneable {
	private int legCount;
	
	public Dog(int legCount) {
		this.legCount = legCount;
	}
	
	public void changeLegCount() {
		this.legCount *= 2;
	}

	@Override
	public String toString() {
		return Integer.toString(this.legCount);
	}
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Dog d = (Dog)super.clone();
		return d;
	}
}

然后在DogClone类的clone方法里加上:

d.dog = (Dog)dog.clone();


DogClone类:

package com.dxy.design.pattern.prototype;

public class DogClone implements Cloneable {
	
	private int legCount;
	
	private Dog dog = new Dog(4);

	@Override
	protected Object clone() throws CloneNotSupportedException {
		DogClone d = (DogClone)super.clone();
		d.dog = (Dog)dog.clone();
		return d;
	}

	public int getLegCount() {
		return legCount;
	}

	public void setLegCount(int legCount) {
		this.legCount = legCount;
	}

	public Dog getDog() {
		return dog;
	}

	public void setDog(Dog dog) {
		this.dog = dog;
	}
}


运行客户端结果如图:

原克隆对象DogClone中的Dog的legCount没有改变,克隆成功。

注意:并不是所有的类都能够实现深度克隆,例如StringBuffer,它没有重载clone()方法,所以它不能实现深度克隆。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值