C# 設計形式系列教程-原型形式。本站提示廣大學習愛好者:(C# 設計形式系列教程-原型形式)文章只能為提供參考,不一定能成為您想要的結果。以下是C# 設計形式系列教程-原型形式正文
1. 概述
經由過程復制一個曾經存在的實例來創立一個新的實例。被復制的實例被稱為原型,這個原型是可定制的。
2. 形式中的腳色
2.1 籠統原型類(Abstract Prototype):供給一個克隆接口
2.2 詳細原型類(Concrete Prototype): 及完成了克隆接口的詳細原型類
3. 實例:求職網站上如今都支撐多份簡歷,假如每創立一份簡歷都要從頭到尾地填寫一遍,那也長短常讓人懊喪的事。其實針對我們的求職崗亭的分歧,分歧的簡歷能夠只需修正部分內容便可以了,而不消全體從新構建一份新的簡歷。復制一份簡歷,然後做部分修正是最使人省心的了!
3.1 完成類圖
類圖解讀
在.NET中,System定名空間曾經為我們供給了一個ICloneable接口,它包括了一個辦法Clone(),完成這個接口就完成了原型形式。
3.2 在寫完成代碼之前,先要懂得一下深復制與淺復制。
3.2.1 淺復制:將本來對象中的一切字段逐一復制到一個新對象,假如字段是值類型,則簡略地復制一個正本到新對象,轉變新對象的值類型字段不會影響原對象;假如字段是援用類型,則復制的是援用,轉變目的對象中援用類型字段的值將會影響原對象。例如, 假如一個對象有一個指向援用類型(如例子中的任務閱歷)的字段, 而且我們對該對象做了一個淺復制, 那麽兩個對象將援用統一個援用(即統一段任務閱歷)。
3.2.2 深復制:與淺復制分歧的地方在於對援用類型的處置,深復制將新對象中援用類型字段指向復制過的新對象,轉變新對象中援用的任何對象,不會影響到本來的對象中對應字段的內容。例如,假如一個對象有一個指向援用類型(如例子中的任務閱歷)的字段,而且對該對象做了一個深復制的話.我門將創立一個新的對象(即新的任務閱歷)。
3.3 簡歷的淺復制完成
/// <summary> /// 完成了ICloneable接口的簡歷類 /// </summary> public class Resume:ICloneable { public Resume() { mWorkExperience = new WorkExperience(); } private string mName; private string mSex; private int mAge; private WorkExperience mWorkExperience; public string Name { get { return mName; } set { mName = value; } } public string Sex { get { return mSex; } set { mSex = value; } } public int Age { get { return mAge; } set { mAge = value; } } /// <summary> /// 聯系關系了一個援用類型 /// </summary> public WorkExperience WorkExperience { get { return mWorkExperience; } } public void SetWorkExperience(DateTime startDate, DateTime endDate, string company, string position) { this.mWorkExperience.Company = company; this.mWorkExperience.EndDate = endDate; this.mWorkExperience.StartDate = startDate; this.mWorkExperience.Position = position; } /// <summary> /// 完成ICloneable接口的Clone辦法 /// </summary> /// <returns></returns> public object Clone() { // .Net 為我們供給的淺復制對象的辦法 return this.MemberwiseClone(); } } /// <summary> /// 任務閱歷類 /// </summary> public class WorkExperience { public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string Company { get; set; } public string Position { get; set; } }
上面是測試代碼
[TestMethod] public void TestShallowCopy() { Resume myFirstResume = new Resume { Age = 29, Name = "Kevin Wang", Sex = "男", }; myFirstResume.SetWorkExperience(new DateTime(2006, 7, 1), new DateTime(2007, 7, 1), "My First Company", "Software Engineer"); Resume mySecondResume = (Resume)myFirstResume.Clone(); mySecondResume.SetWorkExperience(new DateTime(2007, 8, 1), new DateTime(2008, 8, 1), "My Second Company", "Software Engineer"); Resume myThirdResume = (Resume)myFirstResume.Clone(); myThirdResume.SetWorkExperience(new DateTime(2008, 8, 1), new DateTime(2009, 8, 1), "My Third Company", "Senior Software Engineer"); Assert.AreEqual("My First Company", myFirstResume.WorkExperience.Company); Assert.AreEqual("My Second Company", mySecondResume.WorkExperience.Company); Assert.AreEqual("My Third Company", myThirdResume.WorkExperience.Company); }
這裡希冀的是三個斷言都能運轉勝利,然則倒是掉敗的,緣由是:因為我們應用的是淺復制,所以myFirstResume, mySecondResume 和 myThirdResume援用的是統一個對象,是以終究的成果是 三個簡歷的WorkExperience.Company都是“My Third Company".
3.4 簡歷的深復制完成
/// <summary> /// 完成了ICloneable接口的簡歷類 /// </summary> public class Resume : ICloneable { public Resume() { mWorkExperience = new WorkExperience(); } /// <summary> /// 這裡應用一個公有的結構函數來對其銜接到的援用類型停止復制 /// </summary> /// <param name="workExperience"></param> private Resume(WorkExperience workExperience) { this.mWorkExperience = (WorkExperience)workExperience.Clone(); } private string mName; private string mSex; private int mAge; private WorkExperience mWorkExperience; public string Name { get { return mName; } set { mName = value; } } public string Sex { get { return mSex; } set { mSex = value; } } public int Age { get { return mAge; } set { mAge = value; } } public WorkExperience WorkExperience { get { return mWorkExperience; } } /// <summary> /// 設置功過閱歷 /// </summary> /// <param name="startDate"></param> /// <param name="endDate"></param> /// <param name="company"></param> /// <param name="position"></param> public void SetWorkExperience(DateTime startDate, DateTime endDate, string company, string position) { this.mWorkExperience.Company = company; this.mWorkExperience.EndDate = endDate; this.mWorkExperience.StartDate = startDate; this.mWorkExperience.Position = position; } /// <summary> /// 完成ICloneable接口的Clone辦法 /// </summary> /// <returns></returns> public object Clone() { // 這裡不再應用MemberwiseClone辦法停止復制了,而是新創立了一個全新的簡歷。它完整是在外部完成的,內部不消關懷它的完成 Resume newResume = new Resume(this.mWorkExperience); newResume.mSex = this.mSex; newResume.mName = this.mName; newResume.mAge = this.mAge; return newResume; } } public class WorkExperience :ICloneable { public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string Company { get; set; } public string Position { get; set; } public object Clone() { // 應用.Net 為我們供給的淺復制對象的辦法,由於這裡曾經沒有援用對象了(string固然是援用類型,但.NET為我們做了特殊處置,可以像值類型一樣應用它)。 return this.MemberwiseClone(); } }
測試代碼以下
[TestMethod] public void TestDeepCopy() { Resume myFirstResume = new Resume { Age = 29, Name = "Kevin Wang", Sex = "男", }; myFirstResume.SetWorkExperience(new DateTime(2006, 7, 1), new DateTime(2007, 7, 1), "My First Company", "Software Engineer"); Resume mySecondResume = (Resume)myFirstResume.Clone(); mySecondResume.SetWorkExperience(new DateTime(2007, 8, 1), new DateTime(2008, 8, 1), "My Second Company", "Software Engineer"); Resume myThirdResume = (Resume)myFirstResume.Clone(); myThirdResume.SetWorkExperience(new DateTime(2008, 8, 1), new DateTime(2009, 8, 1), "My Third Company", "Senior Software Engineer"); Assert.AreEqual("My First Company", myFirstResume.WorkExperience.Company); Assert.AreEqual("My Second Company", mySecondResume.WorkExperience.Company); Assert.AreEqual("My Third Company", myThirdResume.WorkExperience.Company); }
運轉測試,測試經由過程,這恰是我們希冀的成果。
4. 形式總結
4.1 長處
4.1.1 隱蔽了對象的創立細節,對有些初始化須要占用許多資本的類來講,對機能也有很年夜進步。
4.1.2 在須要新對象時,可使用Clone來疾速創立創立一個,而不消應用new來構建。
4.2 缺陷
4.2.1 每個類都須要一個Clone辦法,並且必需全盤斟酌。關於深拷貝來講,每一個聯系關系到的類型都不准完成IClonable接口,而且每增長或修正一個字段是都須要更新Clone辦法。
4.3 實用場景
4.3.1 類初始化須要消化異常多的資本,這個資本包含數據、硬件資本等
4.3.2 經由過程new發生一個對象須要異常繁瑣的數據預備或拜訪權限,則可使用原型形式
4.3.3 一個對象須要供給給其他對象拜訪,並且各個挪用者能夠都須要修正其值時,可以斟酌應用原型形式拷貝多個對象供挪用者應用。
以上就是本文的全體內容,願望能給年夜家一個參考,也願望年夜家多多支撐。