1. 程式人生 > 實用技巧 >Java的反射機制之反向抽菸

Java的反射機制之反向抽菸

模式定義

原型模式:是一種物件創造型模式,用原型例項指定建立物件的種類,並且通過複製這些原型建立新的物件。原型模式允許一個物件建立另一個可定製的物件,無需知道任何建立新的物件。

模式結構

模式分析

常見的複製黏貼就運用了原型模式,原型模式分為淺克隆和深克隆。

淺克隆:淺克隆僅僅複製所考慮的物件,而不復制他所引用的成員物件。換言之,複製的物件成員物件仍指向源物件的成員物件。

深克隆:複製的物件及成員物件全部複製一遍。

優點:

(1)當建立的物件較複雜時,使用原型模式可以簡化物件的建立。

(2)可以動態的增加或減少產品類

(3)提供了簡化的建立結構,無需專門的工廠類實現物件的複製。

(4)可以使用深克隆的方式儲存物件的狀態。

缺點:

(1)違背“開閉原則”,需要每個類配置一個克隆方法。

(2)在實現深克隆時,需要用到複雜程式碼。

郵件案例

淺克隆

郵件實體類

package com.zck.prototype;

public class ShallowCopyEmail implements Cloneable{
	private ShallowCopyAttachment attachment;
	public ShallowCopyEmail(){
		this.attachment = new ShallowCopyAttachment();
	}
	public Object clone(){
		ShallowCopyEmail clone = null;
		try {
			clone = (ShallowCopyEmail) super.clone();
		} catch (CloneNotSupportedException e) {
			System.out.print("copy faillure");
		}
		return clone;
	}
	public ShallowCopyAttachment getAttachment() {
		return this.attachment;
	}
	public void display(){
		System.out.print("檢視郵件");
	}
}

郵件成員物件類

package com.zck.prototype;
//附件類,是eamil類的成員物件
public class ShallowCopyAttachment {
	
	public void downLoad(){
		System.out.print("下載附件");
	}
}

客戶端測試類

package com.zck.prototype;

public class ShallowCopyClient {

	public static void main(String[] args) {
		ShallowCopyEmail email,copyEmail;
		email = new ShallowCopyEmail();
		copyEmail = (ShallowCopyEmail) email.clone();
		//兩個物件不同,但其成員物件指向同一個物件。
		System.out.println(email == copyEmail);//false
		System.out.println(email.getAttachment() == copyEmail.getAttachment());//true
	}
}

測試結果

深克隆

郵件實體類

package com.zck.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;

public class DeepCopyEmail implements Serializable{
	private DeepCopyAttachment attachment;
	public DeepCopyEmail(){
		this.attachment = new DeepCopyAttachment();
	}
	public Object deepClone() throws IOException, ClassNotFoundException{
		//將物件寫入流
		ByteArrayOutputStream bao = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(bao);
		oos.writeObject(this);
		//將物件從流中取出
		ByteArrayInputStream bis = new ByteArrayInputStream(bao.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bis);
		return (ois.readObject());
	}
	public DeepCopyAttachment getAttachment() {
		return this.attachment;
	}
	public void display(){
		System.out.print("檢視郵件");
	}
}

郵件成員實體類

package com.zck.prototype;

import java.io.Serializable;

public class DeepCopyAttachment implements Serializable{
	public void downLoad(){
		System.out.print("下載附件");
	}
}

客戶端測試類

package com.zck.prototype;

import java.io.IOException;

public class DeepCopyClient {

	public static void main(String[] args) throws ClassNotFoundException, IOException {
		DeepCopyEmail email,copyEmail = null;
		email = new DeepCopyEmail();
		copyEmail = (DeepCopyEmail) email.deepClone();
		//兩個物件不同,但其成員物件指向同一個物件。
		System.out.println(email == copyEmail);//false
		System.out.println(email.getAttachment() == copyEmail.getAttachment());//true
	}
}

測試結果