原型模式

原型模式(Prototype Pattern)是創建型模式(Creation)的一種,創建型型模式是對類的實例化過程的抽象化,能夠提高對象的創建和管理職責。

原型模式的英文原話是:Specify the kinds of objects to create using a prototypical instance,and create new object by copying this prototype。

意思是,用原型實例指定創建對象的種類,並且通過複製這些原型創建新的對象。

原型模式的UML類圖如下所示:


原型模式共設計3個角色:

抽象原型角色(Prototype):該角色是一個抽象角色,通常由一個Java接口或者抽象類實現,給出所有具體原型類所需的接口;

具體原型模式角色(ConcretePrototype):該角色是被複制的對象,必須實現抽象原型接口;

客戶角色(Client):該角色提出創建對象的請求。


原型模式在生成複雜對象比較苦難的環境中比較適用,通過克隆已有對象來實現創建新的對象,節省了時間和空間。


由於Java語言內置了對象的克隆機制,Object類具有一個clone()方法,能夠實現對象的克隆。


原型模式的實例:

一封電子郵件的主題(標題、收件人、內容...)是相同的,我們希望製作一個電子郵件的原型,以後每次放送郵件,只需複製這個原型,然後填上我們定製的內容,這樣就不用每一次放送都new出一個郵件對象。


抽象原型角色

MailPrototype:

public interface MailPrototype extends Cloneable {

	Object clone();
	
}

具體原型角色:

public class ConcreteMail implements MailPrototype {

	private String receiver;
	private String subject;
	private String contxt;
	
	public ConcreteMail(String subject,String contxt) {
		this.subject = subject;
		this.contxt = contxt;
	}
	
	public ConcreteMail clone() {
		try {
			return (ConcreteMail)super.clone();
		}catch (CloneNotSupportedException e) {
			e.printStackTrace();
			return null;
		}
	}

	public String getReceiver() {
		return receiver;
	}

	public void setReceiver(String receiver) {
		this.receiver = receiver;
	}

	public String getSubject() {
		return subject;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public String getContxt() {
		return contxt;
	}

	public void setContxt(String contxt) {
		this.contxt = contxt;
	}
	
}

客戶角色:

public class Client {

	private static int MAX_COUNT = 10;
	
	public static void main(String[] args) {
		ConcreteMail mail = new ConcreteMail("Meeting Notice", "There is meeting at 301 5:00pm");
		for(int i=0;i<MAX_COUNT;i++) {
			mail.clone();
			mail.setReceiver("Dear madam/sir: member " + i);
			send(mail);
			System.out.println("-----------------------------------");
		}
	}
	
	public static void send(ConcreteMail mail) {
		System.out.println("Receiver : " + mail.getReceiver());
		System.out.println("Subject : " +  mail.getSubject());
		System.out.println("\t" + mail.getContxt());
	}
	
}

原型模式的優點:
(1)根據客戶端要求實現動態創建對象
,客戶端不需要知道對象的創建細節,便於代碼的維護和擴展。
(2)使用原型模式創建對象比直接new一個對象在性能上要好的多,因爲Object類的clone方法是一個本地方法,它直接操作內存中的二進制流,特別是複製大對象時,性能的差別非常明顯。所以在需要重複地創建相似對象時可以考慮使用原型模式。比如需要在一個循環體內創建對象,假如對象創建過程比較複雜或者循環次數很多的話,使用原型模式不但可以簡化創建過程,而且可以使系統的整體性能提高很多。

(3) 原型模式類似於工廠模式,但它沒有了工廠模式中的抽象工廠和具體工廠的層級關係,代碼結構更清晰和簡單。


原型模式的注意事項:
(1)使用原型模式複製對象不會調用類的構造方法。因爲對象的複製是通過調用Object類的clone方法來完成的,它直接在內存中複製數據,因此不 會調用到類的構造方法。不但構造方法中的代碼不會執行,甚至連訪問權限都對原型模式無效。還記得單例模式嗎?單例模式中,只要將構造方法的訪問權限設置爲 private型,就可以實現單例。但是clone方法直接無視構造方法的權限,所以,單例模式與原型模式是衝突的。
(2)在使用時要注意
深拷貝與淺拷貝的問題。clone方法只會拷貝對象中的基本的數據類型,對於數組、容器對象、引用對象等都不會拷貝,這就是淺拷貝。如果要實現深拷貝,必須將原型模式中的數組、容器對象、引用對象等另行拷貝。


幾種創建型模式的區別:

Singleton單件模式解決的問題是:實體對象個數問題(這個現在還不太容易混)

AbstractFactory抽象工廠模式解決的問題是:“一系列互相依賴的對象”的創建工作

Builder生成器模式解決的問題是:“一些複雜對象”的創建工作,子對象變化較頻繁,對算法相對穩定

FactoryMethor工廠方法模式解決的問題是:某個對象的創建工作




發佈了65 篇原創文章 · 獲贊 34 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章