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

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

自己对原型模式简单理解的原理图如下:

具体属性没有添加:


原型模式里面关键点就在一个Cloneable接口和clone方法的重写

下面就通过一个配钥匙的例子简单的写了一个程序,起初一个一个抽象类,这样可以重写clone方法,如果是接口的话就得到子类里面把重写的方法具体声明,这样的话对于程序的复用性不是很好,于是就写了一个抽象的类KeyPrototype然后,写了两个子类继承一个客户端,代码如下:

package com.designpattern.prototype;

public abstract class KeyPrototype implements Cloneable {
	private String color;
	private float length;
	private float thick;

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

	@Override
	public String toString() {
		return this.getClass() + " -> Color:" + this.getColor() + " Length:"
				+ this.getLength() + " Thick:" + this.getThick();
	}

	public String getColor() {
		return color;
	}

	public float getLength() {
		return length;
	}

	public float getThick() {
		return thick;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public void setLength(float length) {
		this.length = length;
	}

	public void setThick(float thick) {
		this.thick = thick;
	}

}

package com.designpattern.prototype;

public class CopperKey extends KeyPrototype {
	
}

package com.designpattern.prototype;

public class AluminiumKey extends KeyPrototype {

}

package com.designpattern.prototype;

public class Client {
	public static void main(String[] args) {
		KeyPrototype copperkey = new CopperKey();
		copperkey.setColor("red");
		copperkey.setLength(12);
		copperkey.setThick(2);
		System.out.println(copperkey);

		try {
			KeyPrototype aluminaumkey = (KeyPrototype) copperkey.clone();
			aluminaumkey.setColor("yellow");
			aluminaumkey.setLength(10);
			aluminaumkey.setThick(5);
			System.out.println(aluminaumkey);
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
	}
}

class com.designpattern.prototype.CopperKey -> Color:red Length:12.0 Thick:2.0
class com.designpattern.prototype.CopperKey -> Color:yellow Length:10.0 Thick:5.0
这样就简单对前者进行的复制,很显然他们并不是一个对象,里面关于clone的东西做了一个简单的总结

同时来证明他们确实是两个对象,就是改动里面的属性不互相影响:

首先我创建了一个Dog类

package com.note.clone;

public class Dog/* implements Cloneable  */{
	private String color;
	private String name;
	public Dog(String name,String color){
		this.name = name;
		this.color = color;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public String getName() {
		return name;
	}

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

/*	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}*/

	@Override
	public String toString() {
		return this.getClass()+" "+this.getName()+" "+this.getColor();
	}
	
	
}

然后写了一个Tom类,其中Tom类里面有私有属性Dog

package com.note.clone;

public class Tom implements Cloneable {
	private String color;
	private Dog dog = new Dog("mimi", "yellow");;
	private String name;

	@Override
	protected Object clone() throws CloneNotSupportedException {
		Tom o = null;
		o = (Tom)super.clone();
//		o.setDog((Dog)o.getDog().clone());
		return o;
	}

	public String getColor() {
		return color;
	}

	public Dog getDog() {
		return dog;
	}

	public String getName() {
		return name;
	}

	public void setColor(String color) {
		this.color = color;
	}

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

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

	@Override
	public String toString() {
		return this.getClass() + " " + this.getName() + " " + this.getColor()
				+ "\n" + "Dog:" + this.dog;
	}

}

然后写了一个People类简单的对上述的两个程序进行测试:

package com.note.clone;

public class People {

	public static void main(String[] args) {
		Tom tom = new Tom();
		tom.setName("Tom");
		tom.setColor("blue");
		System.out.println(tom);
		System.out.println();
		
		try {
			Tom tylo = (Tom) tom.clone();
			tylo.setName("tylo");
			tylo.setColor("red");
			tylo.getDog().setName("lucky");
			tylo.getDog().setColor("green");
			System.out.println(tylo);
			System.out.println();
			System.out.println(tom);
			System.out.println();

			Dog dog = tylo.getDog();
			dog.setName("hello");
			dog.setColor("white");
			System.out.println(tylo);
			System.out.println();
			System.out.println(tom);
			System.out.println();

		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}

	}
}

运行结果如下:

class com.note.clone.Tom Tom blue
Dog:class com.note.clone.Dog mimi yellow

class com.note.clone.Tom tylo red
Dog:class com.note.clone.Dog lucky green

class com.note.clone.Tom Tom blue
Dog:class com.note.clone.Dog lucky green

class com.note.clone.Tom tylo red
Dog:class com.note.clone.Dog hello white

class com.note.clone.Tom Tom blue
Dog:class com.note.clone.Dog hello white


这样很明确的表明了对于这两个对象的属性,自己的属性除了Dog以外都是自己的,没有对着对方的属性的改变而改变,但是Dog属性,两个对象的属性是一样的

那么这里就到了深度克隆

我们把Dog和Tom里注释掉的内容打开再运行People程序,运行结果如下:

class com.note.clone.Tom Tom blue
Dog:class com.note.clone.Dog mimi yellow

class com.note.clone.Tom tylo red
Dog:class com.note.clone.Dog lucky green

class com.note.clone.Tom Tom blue
Dog:class com.note.clone.Dog mimi yellow

class com.note.clone.Tom tylo red
Dog:class com.note.clone.Dog hello white

class com.note.clone.Tom Tom blue
Dog:class com.note.clone.Dog mimi yellow

很明显发现,两个对象的Dog属性也没有互相影响,说明了他们不是用的一个引用,这样也证明了上面的例子,他们分别是一个对象,达到了克隆复用的应用。

在原型模式中,可以动态的添加产品分类,而且对整体结构没有影响。

由于原型模式需要给每一个类都配备一个克隆方法,这就需要在这几类的时候通盘考虑,因为在已有类的基础上来添加clone操作时比较困难的,而且原型模式在实现深层的复制时,需要编写一定量的代码。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值