Java设计模式(四):原型模式Prototype

原型模式是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.
原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据.

原型模式中的拷贝分为"浅拷贝"和"深拷贝":
浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.
深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.

类图:



下面我们用克隆羊的例子来示例

package com.iter.devbox.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;

// 克隆
public class Sheep implements Cloneable,Serializable {
	private String sname;
	private Date birthday;

	//利用系统的克隆方法实现克隆对象
	protected Object clone() throws CloneNotSupportedException {
		Sheep s = (Sheep) super.clone();
		// 添加下面代码实现深拷贝。即把成员变量为对象的进行拷贝
		s.birthday = (Date) this.birthday.clone();
		return s;
	}
	/**
	 * 利用串行化来做深复制
	 * 把对象写到流里的过程是串行化(Serilization)过程;
	 * 把对象从流中读出来是并行化(Deserialization)过程. 
	 * 写在流里的是对象的一个拷贝,然后再从流里读出来重建对象.
	 */
	public Object deepClone() {
		try {
			ByteArrayOutputStream bo = new ByteArrayOutputStream();
			ObjectOutputStream oo = new ObjectOutputStream(bo);
			oo.writeObject(this);

			ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
			ObjectInputStream oi = new ObjectInputStream(bi);
			return oi.readObject();
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
			return null;
		}
	}
	public String toString() {
		return this.sname + ": " + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(birthday);
	}
	public Sheep(String sname, Date birthday) {
		super();
		this.sname = sname;
		this.birthday = birthday;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}


package com.iter.devbox.prototype;

import java.util.Calendar;
import java.util.Date;

public class Client {
	public static void main(String[] args) throws CloneNotSupportedException {
		Calendar calendar = Calendar.getInstance();
		calendar.set(1010, 3, 21, 7, 34, 43);
		Date date = new Date(calendar.getTimeInMillis());
		Sheep s1 = new Sheep("111羊",date);
		Sheep s2 = (Sheep) s1.clone();  
		Sheep s3 = (Sheep) s1.deepClone();
		s2.setSname("222羊");
		s3.setSname("333羊");
		System.out.println("改变date之前s1的值==" + s1.toString());
		System.out.println("改变date之前s2的值==" + s2.toString());
		System.out.println("改变date之前s3的值==" + s3.toString() + "\n");
		
		calendar.set(2120, 4, 22, 8, 35, 44);
		date.setTime(calendar.getTimeInMillis());
		
		System.out.println("改变date之后s1的值==" + s1.toString());
		System.out.println("改变date之后s2的值==" + s2.toString());
		System.out.println("改变date之后s3的值==" + s3.toString());
	}
}
运行结果:

改变date之前s1的值==111羊: 1010-04-21 07:34:43
改变date之前s2的值==222羊: 1010-04-21 07:34:43
改变date之前s3的值==333羊: 1010-04-21 07:34:43


改变date之后s1的值==111羊: 2120-05-22 08:35:44
改变date之后s2的值==222羊: 1010-04-21 07:34:43
改变date之后s3的值==333羊: 1010-04-21 07:34:43


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章