原型模式是創建型模式的一種,其特點在於通過「複製」一個已經存在的實例來返回新的實例,而不是新建實例。被複制的實例就是我們所稱的「原型」,這個原型是可定製的。
Prototype原型模式是一種創建型設計模式,它主要面對的問題是:“某些結構複雜的對象”的創建工作;由於需求的變化,這些對象經常面臨着劇烈的變化,但是他們卻擁有比較穩定一致的接口。
例子:
public class WeeklyLog implements Cloneable
{
private String name;
private String date;
private String content;
public void setName(String name){
this.name = name;
}
public void setDate(String date){
this.date = date;
}
public void setContent(String content){
this.content = content;
}
public String getName(){
return (this.name);
}
public String getDate(){
return (this.date);
}
public String getContent(){
return (this.content);
}
public Object clone()
{
Object obj = null;
try
{
obj = super.clone();
return obj;
}
catch (CloneNotSupportedException e)
{
System.out.println("不能複製!");
return null;
}
}
}
public class Client
{
public static void main(String[] args) {
WeeklyLog log_previous = new WeeklyLog();
log_previous.setName("張三");
log_previous.setDate("2018年 第 12 周");
log_previous.setContent("這周工作很忙,每天加班!");
System.out.println("*** 週報 ***");
System.out.println(log_previous.getDate());
System.out.println(log_previous.getName());
System.out.println(log_previous.getContent());
System.out.println("-----------------------------------------");
WeeklyLog log_now;
log_now = (WeeklyLog)log_previous.clone();
log_now.setDate("2018年 第 13 周");
System.out.println("*** 週報 ***");
System.out.println(log_now.getDate());
System.out.println(log_now.getName());
System.out.println(log_now.getContent());
}
}
在本實例中使用了Java語言內置的潛克隆機制,通過繼承Object類的clone()方法實現對象的複製,原始對象和克隆得到的對象在內存中是兩個完全不同的對象,通過已創建的工作週報可以快速創建新的週報,然後再根據需要修改週報,無須再從頭開始創建。原型模式爲工作流系統中任務單的快速生成提供了一種解決方案。
淺克隆和深克隆
無論你是自己實現克隆方法,還是採用Java提供的克隆方法,都存在一個淺度克隆和深度克隆的問題。
只負責克隆按值傳遞的數據(比如基本數據類型、String類型),而不復制它所引用的對象,換言之,所有的對其他對象的引用都仍然指向原來的對象。
除了淺度克隆要克隆的值外,還負責克隆引用類型的數據。那些引用其他對象的變量將指向被複制過的新對象,而不再是原有的那些被引用的對象。換言之,深度克隆把要複製的對象所引用的對象都複製了一遍,而這種對被引用到的對象的複製叫做間接複製。
深度克隆要深入到多少層,是一個不易確定的問題。在決定以深度克隆的方式複製一個對象的時候,必須決定對間接複製的對象時採取淺度克隆還是繼續採用深度克隆。因此,在採取深度克隆時,需要決定多深纔算深。此外,在深度克隆的過程中,很可能會出現循環引用的問題,必須小心處理。