引言:html
原型,感受就是拷貝,只是給拷貝分了深拷貝和淺拷貝。this
理解:spa
在C#.Net裏面,咱們能夠很容易的經過Clone()方法實現原型模式。.net
任何類,只要想支持克隆,必須實現C#中的ICloneable接口。設計
ICloneable接口中有一Clone方法,能夠在類中複寫實現自定義的克隆方法。指針
克隆的實現方法有兩種:淺拷貝(shallow copy)與深拷貝(deep copy)。code
說明:淺拷貝是指當對象的字段值被拷貝時,字段引用的對象不會被拷貝。而深拷貝是對對象實例中字段引用的對象也進行拷貝的一種方式。htm
UML圖:(出之http://www.cnblogs.com/zhenyulu/articles/39257.html)對象
示例代碼:blog
public interface IObjectOne { IObjectOne Clone(); void Write(); } // Object public class Object1 : IObjectOne { public String _val = "A"; public User _user = new User(); public IObjectOne Clone() { _user.Name = "A name"; return (IObjectOne)this.MemberwiseClone(); } public void Write() { Console.WriteLine(_user.Name); Console.WriteLine("Object " + _val); } } // 實體 public class User { public String Name { get; set; } }
調用
static void Main(string[] args) { Object1 obj = new Object1(); Object1 objCopy = (Object1)obj.Clone(); // 值類型 objCopy._val = "AA"; // 引用類型 objCopy._user.Name = "AA name"; objCopy.Write(); obj.Write(); Console.ReadKey(); }
結果
從結果咱們看出,MemberwiseClone方法是淺拷貝,由於只有值類型的被拷貝了,引用類型的沒有被拷貝。
理解拷貝:
public interface IObjectTwo { // 淺拷貝 IObjectTwo Clone(); // 深拷貝 IObjectTwo DeepClone(String name); // 輸出 void Write(); } public class Object3 : IObjectTwo { public String _val = "A"; public User _user = new User(); public Object3() { _user.Name = "A name"; } // 淺拷貝 public IObjectTwo Clone() { return (IObjectTwo)this.MemberwiseClone(); } // 深拷貝 public IObjectTwo DeepClone(String name) { Object3 nowObj = new Object3(); User obj = new User(); obj.Name = name; nowObj._val = this._val; nowObj._user = obj; return (IObjectTwo)nowObj; } // 輸出 public void Write() { Console.WriteLine(_user.Name); Console.WriteLine("Object " + _val); } }
static void Main(string[] args) { Object1 obj = new Object1(); Object1 objCopy = (Object1)obj.Clone(); // 值類型 objCopy._val = "AA"; // 引用類型 objCopy._user.Name = "AA name"; objCopy.Write(); obj.Write(); Console.WriteLine(); Console.WriteLine("--------------------"); Console.WriteLine(); Object3 nowObj = new Object3(); Object3 objCopy2 = (Object3)nowObj.Clone(); objCopy2._val = "XX"; objCopy2._user.Name = "XX name"; objCopy2.Write(); // 深拷貝 Object3 objCopy3 = (Object3)nowObj.DeepClone("My Name"); objCopy3._val = "YY"; objCopy3.Write(); objCopy3._user.Name = "Test"; objCopy3.Write(); nowObj.Write(); Console.ReadKey(); } }
結果:
從結果知道,拷貝一個引用類型,必定是New這個對象。這個其實跟堆棧有關,當new一個對象時,會在堆上面新分配一個區域,用於新對象的存儲。
可是給一個引用對象賦值另外一個引用對象時,是把引用的指針給了對象,並無從新分配存儲區域,因此修改這個對象就會影響,整個上下文中的這個對象,
由於,修改的是一個存儲區域。
總結:(出之http://www.cnblogs.com/zhenyulu/articles/39257.html)
一、Prototype模式容許動態增長或減小產品類。因爲建立產品類實例的方法是產批類內部具備的,所以增長新產品對整個結構沒有影響。
二、Prototype模式提供了簡化的建立結構。工廠方法模式經常須要有一個與產品類等級結構相同的等級結構,而Prototype模式就不須要這樣。
三、Portotype模式具備給一個應用軟件動態加載新功能的能力。因爲Prototype的獨立性較高,能夠很容易動態加載新功能而不影響老系統。
四、產品類不須要非得有任何事先肯定的等級結構,由於Prototype模式適用於任何的等級結構。
應用場景:
如:一個方法,裏面的參數是一個實體類,ProcessMessage(User userInfo),而調用這個方法的方法是ReturnProcess()
public void ReturnProcess(){
User userInfo = new User();
// 調用前
......
ProcessMessage(userInfo);
//調用後
......
}
那麼,在ProcessMessage修改對象uerInfo,會直接影響到 調用後,userInfo的值。
因此在一些設計中須要考慮子方法中修改對象帶來的影響,
因此咱們須要深拷貝和淺拷貝。
也就是咱們說的原型模式。
代碼下載: