日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

设计模式之C#实现---- ProtoType

發布時間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式之C#实现---- ProtoType 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
作者: cuike519的專欄?? http://blog.csdn.net/cuike519/

該模式的意圖是:用原型實例指定創建對象的種類,并且通過拷貝這些原型創建新的對象。那么首先我們應該已經有了一個對象,同時這個對象還支持自我復制(科隆)。在FCL里面我們知道有一個接口專門用來規定這么一個契約,那就是ICloneable接口,該接口只有一個方法Clone,以下MSDN對該接口中對該接口的方法的說明:創建作為當前實例副本的新對象。Clone 既可作為深層副本實現,也可作為淺表副本實現。在深層副本中,所有的對象都是重復的;而在淺表副本中,只有頂級對象是重復的,并且頂級以下的對象包含引用。結果克隆必須與原始實例具有相同的類型或是原始實例的兼容類型。這樣一來如果我們想要一個可以自我復制的對象我們可以申明一個類MyClass該類繼承接口ICloneable

下面我們舉一個顯示生活中的例子來說明這種方法是普遍存在的的。我想我們可能都知道細胞,細胞是組成機體的最小單位(也許不是),我們知道任何(也許是部分)動物或者植物都是由一個細胞分裂的來的,所以我們可以理解細胞就是一種帶有Clone方法的對象,細胞可以不斷的調用該方法是我們的機體趨于完整。還可以舉一個例子就是病毒,我們都經歷過Sars期間,我想如果Sars沒有自我復制的功能它就不可能成氣候,還有一個人人都要實現的例子就是錢(我不知道是不是恰當),我們可以通過我們的努力使得1塊錢變成2當然每個人的實現方法不同自然結果也就不同了(不知道是否貼切)。當然上面所據的前兩個例子應該都是一種深層副本,因為他一旦被復制就是一個獨立的個體,在內存中就是不同的兩個地址,而潛表拷貝則不同,表面上看是兩個實際上是一個對象的兩個引用,也就是實際上他們存在于同一個地址,如果我們改變其中一個那么另一個也會改變。應此我們可以看出應用這種模式的關鍵就是如何實現Clone的方法。

?????? 下面是PROTOTYPE的結構圖(來自ROSE2003):

?????? 淺拷貝和深拷貝之間的區別:淺拷貝是指將對象中的數值類型的字段拷貝到新的對象中,而對象中的引用型字段則指復制它的一個引用到目標對象。如果改變目標對象中引用型字段的值他將反映在原是對象中,也就是說原始對象中對應的字段也會發生變化。深拷貝與淺拷貝不同的是對于引用的處理,深拷貝將會在新對象中創建一個新的和原是對象中對應字段相同(內容相同)的字段,也就是說這個引用和原是對象的引用是不同的,我們在改變新對象中的這個字段的時候是不會影響到原始對象中對應字段的內容。所以對于原型模式也有不同的兩種處理方法:對象的淺拷貝和深拷貝。在FCL中的System命名空間下面有一個淺拷貝的方法叫:MemberwiseClone它是創建當前 Object 的淺表副本。在我們的例子里我想實現一個淺拷貝同時在實現一個深拷貝,這樣可以加深理解。

下面是一個淺拷貝的例子:

using System;

namespace Prototype_Shallow{

?????? //因為我們在FCL里面已經有這樣的接口所以我們就不定義新的Prototype

?????? public class ConcretePrototype1 : ICloneable{

????????????? private int m_ID;

????????????? public int ID{

???????????????????? get{

??????????????????????????? return this.m_ID;

???????????????????? }

????????????? }

????????????? public ConcretePrototype1(int id){

???????????????????? this.m_ID = id;

????????????? }

????????????? public object Clone(){

???????????????????? return this.MemberwiseClone();

????????????? }

?????? }

?????? public class ConcretePrototype2 : ICloneable{

????????????? private int m_ID;

????????????? public int ID

????????????? {

???????????????????? get

???????????????????? {

??????????????????????????? return this.m_ID;

???????????????????? }

????????????? }

????????????? public ConcretePrototype2(int id){

???????????????????? this.m_ID = id;

????????????? }

????????????? public object Clone(){

???????????????????? return this.MemberwiseClone();

????????????? }

?????? }

}

我們具體的原型都繼承了接口ICloneable,同時也實現了該接口里面唯一個一個方法Clone。我們可以在客戶端這樣創建對象ConcretePrototype1 p1 = new ConcretePrototype1(1);?????? ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();首先我們創建了對象p1,接下來我們用通過p1的科隆方法得到了對象c1,這就是一種淺拷貝(因為MemberwiseClone是淺拷貝)。

?????? 接下來我們將要實現的是深拷貝,這個一個相對淺拷貝比較困難的工作,我們在拷貝對象的時候不但要拷貝他的數值型字段同時還要復制它的引用字段(有的時候這種工作是非常困難的也許是不可能的)。

namespace Prototype_Deep{

?????? using System.Collections;

?????? public class ConcretePrototype : ICloneable

?????? {

????????????? private int m_ID;

????????????? public int ID

????????????? {

???????????????????? get

???????????????????? {

??????????????????????????? return this.m_ID;

???????????????????? }

????????????? }

????????????? private ArrayList m_arrayList = new ArrayList();

????????????? public ConcretePrototype(int id)

????????????? {

???????????????????? this.m_ID = id;

???????????????????? this.m_arrayList.Add("FirstObject");

???????????????????? this.m_arrayList.Add("SecondObject");

???????????????????? // ...

????????????? }

????????????? public object Clone()

????????????? {

???????????????????? ConcretePrototype c = new ConcretePrototype(this.ID);

???????????????????? c.m_arrayList = new ArrayList();

???????????????????? c.m_arrayList.Add("FirstObject");

???????????????????? c.m_arrayList.Add("SecondObject");

???????????????????? return c;

????????????? }

????????????? public ConcretePrototype DeepClone(){

???????????????????? return (ConcretePrototype)this.Clone();

????????????? }

?????? }

}

?????? 該代碼顯示了如何實現深拷貝,深拷貝的原則就是對于那些引用的字段您需要newnew之前想想是不是能用前面學過的某個創建型的模式實現,這是一個好的習慣)一個出來,然后對該字段里面的對象一一拷貝,這樣以來很容易出現循環拷貝,所以說深拷貝要比淺拷貝更難一些。客戶端可以通過ConcretePrototype p = new ConcretePrototype(1);ConcretePrototype c = p.DeepClone();來實現克隆一個新的對象。代碼如下:

ConcretePrototype p = new ConcretePrototype(1);

???????????????????? ConcretePrototype c = p.DeepClone();

???????????????????? this.richTextBox1.AppendText(p.ToString()+":"+p.ID.ToString()+"/n");

???????????????????? this.richTextBox1.AppendText(c.ToString()+":"+c.ID.ToString()+"/n");

???????????????????? c.m_arrayList[0] = "Changed";

???????????????????? for(int i = 0;i<=1;i++){

??????????????????????????? this.richTextBox1.AppendText(c.m_arrayList[i].ToString());

???????????????????? }

???????????????????? this.richTextBox1.AppendText("/n");

???????????????????? for(int i = 0;i<=1;i++){

??????????????????????????? this.richTextBox1.AppendText(p.m_arrayList[i].ToString());

???????????????????? }

這樣我們將看到結果我們在改變科隆出來的對象的時候原來的對象是不變的。前面的淺拷貝我們有做這種比較,有興趣的讀者可以試一試,在FCL中大部分的科隆都是淺拷貝,我們可以看看實現ICloneable接口的類,幾乎全部都是淺拷貝。順便說一下在工作流中關于處理(Process)對象以及其他的相關對象我們可以使用這種Clone的方法,這個您可以參看CRMWorkFlow中的類,又很多都實現了該方法。

希望我的文章可以幫助您很好的理解設計模式中的原型,關于該模式中的詳細信息您可以參看GOF的書上面說得很清楚。在這次實現中我們利用了FCL的接口,沒有自己寫接口但是效果是一樣的。如果在文章中出現什么不對的地方忘網友指正:wu_jian830@hotmail.com謝謝您的支持,希望我們可以共同進步。

總結

以上是生活随笔為你收集整理的设计模式之C#实现---- ProtoType的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。