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

設計模式——原型模式

編輯:C#入門知識

原型模式         為了解決類似於從一個對象再創建另外一個可定制的對象,而不需要知道任何創建的細節問題,產生了原型模式。用原型實例指定創建對象的種類,並通過拷貝這些原型創建新的對象。   結構圖
  基本原型模式的實現代碼   <span style="font-size:18px;">namespace 原型模式   {       class Program       {           static void Main(string[] args)           {                                 ConcretePrototype1 p1 = new ConcretePrototype1("I");                  //克隆類ConcretePrototype1的對象p1就能得到新的實例c1               ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();               Console.WriteLine("Cloned:{0}", c1.Id);                  Console.Read();           }       }                 //原型類       abstract class Prototype        {           private string id;           public Prototype(string id)           {               this.id = id;           }           public string Id           {               get { return id; }           }              //在抽象類中聲明一個克隆的方法           public abstract Prototype Clone();       }                 //具體原型類       class ConcretePrototype1 : Prototype        {           public ConcretePrototype1(string id)               : base(id)           { }              public override Prototype Clone()           {               //創建當前對象的淺副表本               return (Prototype)this.MemberwiseClone();           }          }            }</span>             MemberwiseClone()方法是創建一個新對象,然後將當前對象的非靜態字段復制到該新對象。如果字段是值類型的,則對該字段執行逐位復制。如果字段是引用類型,則復制引用但不復制引用的對象;因此,原始對象及其副本引用同一對象。           對於.Net而言,那個原型抽象類Prototype是用不著的,因為克隆是在是太常用了,所以.Net在System命名空間中提供了ICloneable接口,其中就是唯一的一個方法Clone(),這樣只需要實現這個接口就可以完成原型模式了。   例子 例如,復制一份簡歷,簡歷的原型實現 實現 [csharp]  <span style="font-size:18px;">//簡歷類       class Resume:ICloneable         {           private string name;           private string sex;           private string age;           private string timeArea;           private string company;              public Resume(string name)           {               this.name = name;           }              //設置個人信息           public void SetPersonalInfo(string sex, string age)           {               this.sex = sex;               this.age = age;           }              //設置工作經歷           public void SetWorkExperience(string timeArea, string company)           {               this.timeArea = timeArea;               this.company = company;              }              //顯示           public void Display()           {               Console.WriteLine("{0}{1}{2}", name, sex, age);                              //實現接口的方法,用來克隆對象               Console.WriteLine("工作經歷:{0}{1}", timeArea, company);           }              public object Clone()           {               return (Object)this.MemberwiseClone();           }       }</span>            一般在初始化的信息不發生變化的情況下,克隆是最好的辦法,這既隱藏了對象創建的細節,又大大的提高了性能。等於是不用重新初始化對象,而是動態地獲得對象運行時的狀態。   淺復制       被復制對象的所有變量都含有與原來的對象相同的值,而所有的對其他對象的引用仍然指向原來的對象。也就是說,淺復制僅僅復制所考慮的對象,而不復制它所引用的對象。   我們先來看一個例子,簡歷復制。 結構圖   代碼實現   工作經歷類 [csharp]   <span style="font-size:18px;"> //工作經歷       class WorkExperience       {           private string workDate;           public string WorkDate           {               get { return workDate; }               set { workDate = value; }           }              private string company;           public string Company            {               get { return company; }               set { company = value; }           }          }</span>     簡歷類 [csharp]   <span style="font-size:18px;">  //簡歷類       class Resume:ICloneable         {           private string name;           private string sex;           private string age;              //引用"工作經歷"對象           private WorkExperience work;                 public Resume(string name)           {               this.name = name;                              //在"簡歷"類實例化時同時實例化"工作經歷"               work = new WorkExperience();           }              //設置個人信息           public void SetPersonalInfo(string sex, string age)           {               this.sex = sex;               this.age = age;           }              //設置工作經歷           public void SetWorkExperience(string workDate, string company)           {                              work.WorkDate = workDate;                              //調用此方法時,給對象的兩個屬性賦值               work.Company = company;                             }              //顯示           public void Display()           {               Console.WriteLine("{0}{1}{2}", name, sex, age);               Console.WriteLine("工作經歷:{0}{1}", work.WorkDate , work.Company);           }              public object Clone()           {               return (Object)this.MemberwiseClone();           }       }</span>     客戶端調用代碼 [csharp]   <span style="font-size:18px;"> class Program       {           static void Main(string[] args)           {               Resume a = new Resume("大鳥");               a.SetPersonalInfo("男", "29");               a.SetWorkExperience("1998-2000","XX公司");                                Resume b = (Resume)a.Clone();               b.SetWorkExperience("1998-2006", "YY企業");                  Resume c = (Resume)a.Clone();               c.SetPersonalInfo("男", "24");               c.SetWorkExperience("1998-2003","ZZ企業");                   //b和c都克隆於a,但當它們都設置了“工作經歷”時,我們希望的結果是三個的顯示不一樣               a.Display();               b.Display();               c.Display();                  Console.Read();                    }       }</span>     結果顯示:             三個版本信息引用的都是最後一次的設置 ,這是因為,只復制引用,而不復制引用的對象,克隆的過程中並沒有創建對象,現在三個引用都指向了同一個工作經歷對象。 這就是淺復制,被復制的對象的所有變量都含有與原來的對象相同的值,但所有的對其他對象的引用都仍然指向原來的對象。   深復制        被復制對象的所有變量都含有與原來的對象相同的值,除去那些引用其他對象的變量。那些引用其他對象的變量將指向被復制過得新對象,而不再是原有的那些被引用的對象。也就是說把要復制的對象所引用的對象都復制了一遍。      還是以簡歷復制為例。 結構圖 代碼實現 簡歷類 [csharp]   <span style="font-size:18px;">//簡歷       class Resume:ICloneable         {           private string name;           private string sex;           private string age;              private WorkExperience work;                 public Resume(string name)           {               this.name = name;               work = new WorkExperience();           }                         //提供Clone方法調用的私有構造函數,以便克隆“工作經歷”的數據           //與淺復制的不同之處           private Resume(WorkExperience work)           {               this.work = (WorkExperience)work.Clone();           }              //設置個人信息           public void SetPersonalInfo(string sex, string age)           {               this.sex = sex;               this.age = age;           }              //設置工作經歷           public void SetWorkExperience(string workDate, string company)           {               work.WorkDate = workDate;               work.Company = company;                             }              //顯示           public void Display()           {               Console.WriteLine("{0}{1}{2}", name, sex, age);               Console.WriteLine("工作經歷:{0}{1}", work.WorkDate , work.Company);           }              //克隆           public object Clone()              {               //調用私有的構造方法,讓“工作經歷”克隆完成,               //然後再給簡歷對象的相關字段賦值,最終返回一個深復制的簡歷對象               Resume obj = new Resume(this.work);               obj.name = this.name;               obj.sex = this.sex;               obj.age = this.age;               return obj;                          }       }</span>     工作經歷類 [csharp]   <span style="font-size:18px;"> //工作經歷       //工作經歷類實現接口       class WorkExperience:ICloneable        {           private string workDate;           public string WorkDate           {               get { return workDate; }               set { workDate = value; }           }              private string company;           public string Company            {               get { return company; }               set { company = value; }           }              public Object Clone()           {                  //工作經歷類實現克隆方法                return (Object)this.MemberwiseClone();           }          }</span>     運行結果          運行結果不同,a,b,c引用的對象都是不同的,復制時就一變二,二變三。        深復制把引用對象的變量指向復制過得新對象,而不是原有的被引用的對象。          由於在特定的場合,會經常涉及深復制或淺復制,比如說,數據集對象DataSet,它就有Clone()方法和Copy()方法,Clone()方法用來復制DataSet結構,但不復制DataSet的數據,實現了原型模式的淺復制。Copy()方法不但復制結構,也復制數據,其實就是實現了原型模式的深復制。      

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