程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# 設計形式系列教程-原型形式

C# 設計形式系列教程-原型形式

編輯:C#入門知識

C# 設計形式系列教程-原型形式。本站提示廣大學習愛好者:(C# 設計形式系列教程-原型形式)文章只能為提供參考,不一定能成為您想要的結果。以下是C# 設計形式系列教程-原型形式正文


1. 概述

  經由過程復制一個曾經存在的實例來創立一個新的實例。被復制的實例被稱為原型,這個原型是可定制的。

2. 形式中的腳色

  2.1 籠統原型類(Abstract Prototype):供給一個克隆接口

  2.2 詳細原型類(Concrete Prototype): 及完成了克隆接口的詳細原型類

3. 實例:求職網站上如今都支撐多份簡歷,假如每創立一份簡歷都要從頭到尾地填寫一遍,那也長短常讓人懊喪的事。其實針對我們的求職崗亭的分歧,分歧的簡歷能夠只需修正部分內容便可以了,而不消全體從新構建一份新的簡歷。復制一份簡歷,然後做部分修正是最使人省心的了!

  3.1 完成類圖

https://www.aspphp.online/bianchen/UploadFiles_4619/201707/2017072810423049.png

  類圖解讀

  在.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 一個對象須要供給給其他對象拜訪,並且各個挪用者能夠都須要修正其值時,可以斟酌應用原型形式拷貝多個對象供挪用者應用。

以上就是本文的全體內容,願望能給年夜家一個參考,也願望年夜家多多支撐。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved