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 一個對象須要供給給其他對象拜訪,並且各個挪用者能夠都須要修正其值時,可以斟酌應用原型形式拷貝多個對象供挪用者應用。
以上就是本文的全體內容,願望能給年夜家一個參考,也願望年夜家多多支撐。