原型模式:使用原型實例指定待創建對象的類型,並且
通過復制這個原型來創建新的對象。
分析:
孫悟空:根據自己的形狀
復制(克隆)
出多個身外身
軟件開發:通過復制一個
原型對象
得到多個與原型對象一模
一樣的新對象
工作原理:
將一個原型對象傳給要發動創建的對象(即客戶端對
象),這個要發動創建的對象
通過請求原型對象復制自己來實現
創建過程
創建新對象(也稱為克隆對象)的
工廠
就是
原型類
自身,
工廠方
法
由負責復制原型對象的
克隆方法
來實現
通過克隆方法所創建的對象是
全新的對象
,它們在內存中擁有新
的地址,每一個克隆對象都是
獨立
的
通過不同的方式對克隆對象進行修改以后,
可以得到一系列相似
但不完全相同的對象
原型模式的結構
原型模式包含以下
3
個角色:
•Prototype(抽象原型類)
•ConcretePrototype(具體原型類)
•Client(客戶類)
淺克隆與深克隆
淺克隆
(Shallow Clone)
:
當原型對象被復制時,
只復制它
本身和其中包含的值類型的成員變量,而引用類型的成員變
量並沒有復制
深克隆
(Deep Clone)
:
除了對象本身被復制外,
對象所包
含的所有成員變量也將被復制
案例:
[Serializable] //深克隆時需要將類標記為Serializable public class Person:ICloneable { public string CurrentEmployee { get; set; } public Member Member { get; set; } public Person() { this.CurrentEmployee = "admin"; Member member = new Member(); member.Id = 3; member.Name = "Mem"; this.Member = member; } public object Clone() { return this.MemberwiseClone(); } #region 靜態方式創建對象 private static Person _person; /// <summary> /// 靜態構造函數,永遠只運行一次 /// </summary> static Person() { _person = new Person(); } public static Person StaticClone() { return _person.MemberwiseClone() as Person; } #endregion }
[Serializable] public class Member { public int Id { get; set; } public string Name { get; set; } }
public class SerializeHelper { /// <summary> /// 序列化 /// </summary> /// <param name="target"></param> /// <returns></returns> public static string Serializable(object target) { using(MemoryStream stream=new MemoryStream()) { new BinaryFormatter().Serialize(stream,target); return Convert.ToBase64String(stream.ToArray()); } } /// <summary> /// 反序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="target"></param> /// <returns></returns> public static T Derializable<T>(string target) { byte[] targetArray = Convert.FromBase64String(target); using (MemoryStream stream = new MemoryStream(targetArray)) { return (T)(new BinaryFormatter().Deserialize(stream)); } } /// <summary> /// 合並反序列化與序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="t"></param> /// <returns></returns> public static T DeepClone<T>(T t) { return Derializable<T>(Serializable(t)); } }
調用:
//淺表克隆,原來創建的對象值會改變 Person p = new Person(); Person p1 = p.Clone() as Person; p1.CurrentEmployee = "user"; p1.Member.Id = 1; p1.Member.Name = "pp1"; //深度克隆,原來創建的對象值不會改變 Person p2 = p.Clone() as Person; Person p3 = SerializeHelper.Derializable<Person>(SerializeHelper.Serializable(p2)); //或者簡寫 //Person p3 = SerializeHelper.DeepClone<Person>(p2); p3.Member.Id = 6; p3.Member.Name = "dd3"; Console.Read();