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


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