說明:1..NET在System命名空間中提供了ICloneable接口,其中只有唯一的一個方法Clone(),只需要實現這個接口就可以完成原型模式。【即上圖中Prototype用ICloneable代替】
2.MemberwiseClone():創建一個淺表副本,方法是創建一個新對象,然后將當前對象的非靜態字段復制到該新對象。 如果字段是值類型的,則對該字段執行逐位復制。 如果字段是引用類型,則復制引用但不復制引用的對象;因此,原始對象及其復本引用同一對象。【對於內部的Class對象和數組,則Copy一份地址;而對於其它內置的int/string/enum/struct/object類型,則Copy一份值(參考:C# 淺拷貝與深拷貝區別)】
一、簡歷復印示例:
1.具體原型類:
public class Resume:ICloneable { private string name; private string timeArea; private string company; public Resume(string name) { this.name = name; } public void SetWorkExperience(string timeArea,string company) { this.timeArea = timeArea; this.company = company; } public void Display() { Console.WriteLine("{0} 工作經歷:{1} {2}", name,timeArea, company); } public object Clone() { return (object)this.MemberwiseClone(); } }
2.客戶端調用:
class Program { static void Main(string[] args) { Resume a = new Resume("a"); a.SetWorkExperience("1998-2000", "X公司"); Resume b = (Resume)a.Clone(); b.SetWorkExperience("1998-2006", "Y公司"); a.Display(); b.Display(); } }
二、簡歷的深復制示例:
說明:參考上圖若Resume類中包含WorkExperience類,則在上面的[簡歷復印示例]中,Resume復制對WorkExperience的復制為淺復制,不同的Resume對象對WorkExperience指向同一個引用。
1.原型包含類:
public class WorkExperience:ICloneable { public string WorkDate { get; set; } public string Company { get; set; } public object Clone() { return (object)this.MemberwiseClone(); } }
2.具體原型類:
public class Resume:ICloneable { private string name; private WorkExperience workExperience; public Resume(string name) { this.name = name; workExperience = new WorkExperience(); } //提供Clone方法調用的私有構造函數,以便克隆“工作經歷”的數據 private Resume(WorkExperience workExperience) { this.workExperience = (WorkExperience)workExperience.Clone(); } public void SetWorkExperience(string workDate,string company) { workExperience.WorkDate = workDate; workExperience.Company = company; } public void Display() { Console.WriteLine("{0} 工作經歷:{1} {2}", name,workExperience.WorkDate, workExperience.Company); } public object Clone() { Resume resume = new Resume(this.workExperience); resume.name = this.name; return resume; } }
3.客戶端調用:
class Program { static void Main(string[] args) { Resume a = new Resume("a"); a.SetWorkExperience("1998-2000", "X公司"); Resume b = (Resume)a.Clone(); a.Display(); b.Display(); } }
原型模式其實就是從一個對象再創建另外一個可定制的對象,而不需要知道任何創建的細節。