1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace 原型模式 7 { 8 /// <summary> 9 /// 原型类 10 /// 浅克隆vs深克隆 11 /// 原型创建对象速度更快,与单例不同,当某一个克隆对象的属性进行更改时,其它的克隆对象不会更改 12 /// </summary> 13 [Serializable] 14 class StudentPrototype 15 { 16 public string id { get; set; } 17 public string name { get; set; } 18 public Family family { get; set; } 19 private StudentPrototype() 20 { 21 22 } 23 private static StudentPrototype _prototype = null; 24 25 /// <summary> 26 /// 静态构造函数创建对象 27 /// </summary> 28 static StudentPrototype() 29 { 30 _prototype = new StudentPrototype() 31 { 32 id = "001", 33 name = "张三", 34 family = new Family() 35 { 36 Member="父母,自己", 37 Address="大街" 38 } 39 }; 40 } 41 42 /// <summary> 43 ///浅克隆 44 /// </summary> 45 /// 46 public static StudentPrototype ShallowClone 47 { 48 get 49 { 50 // 与单例稍微有点差别,浅克隆,该对象的属性是值类型可进行 51 StudentPrototype proto = (StudentPrototype)_prototype.MemberwiseClone(); 52 return proto; 53 } 54 } 55 56 /// <summary> 57 /// 深克隆 58 /// </summary> 59 public static StudentPrototype DeepClone 60 { 61 get 62 { 63 return SerializeHelper.DeepClone<StudentPrototype>(_prototype); 64 } 65 } 66 } 67 68 [Serializable] 69 class Family 70 { 71 public string Member { get; set; } 72 public string Address { get; set; } 73 } 74 }
接下来写一个序列化和反序列化类供原型类调用
1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using System.Runtime.Serialization.Formatters.Binary; 6 using System.Text; 7 using System.Web.Script.Serialization; 8 9 namespace 原型模式 10 { 11 class SerializeHelper 12 { 13 public static string Serlizer<T>(T data) 14 { 15 try 16 { 17 using (var stream=new MemoryStream()) 18 { 19 new BinaryFormatter().Serialize(stream, data); 20 return Convert.ToBase64String(stream.ToArray()); 21 } 22 23 } 24 catch (Exception) 25 { 26 return null; 27 } 28 } 29 public static T DeSerlizer<T>(string data) 30 { 31 try 32 { 33 byte[] buffer = Convert.FromBase64String(data); 34 using (var stream=new MemoryStream(buffer)) 35 { 36 return (T)new BinaryFormatter().Deserialize(stream); 37 } 38 } 39 catch (Exception) 40 { 41 return default(T); 42 } 43 } 44 public static T DeepClone<T>(T data) 45 { 46 return DeSerlizer<T>(Serlizer<T>(data)); 47 } 48 } 49 }
在主程序中用调用原型类
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace 原型模式 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 try 13 { 14 StudentPrototype pro1 = StudentPrototype.DeepClone; 15 StudentPrototype pro2 = StudentPrototype.DeepClone; //深克隆 16 pro2.id = "002"; 17 pro2.name = "李四"; 18 pro2.family.Member = "只有我"; 19 pro2.family.Address = "小巷"; 20 Console.WriteLine("ID为{0},name为{1},成员为{2},地址为{3}", pro1.id, pro1.name, pro1.family.Member, pro1.family.Address); 21 Console.WriteLine("ID为{0},name为{1},成员为{2},地址为{3}", pro2.id, pro2.name, pro2.family.Member, pro2.family.Address); 22 Console.ReadLine(); 23 } 24 catch (Exception) 25 { 26 throw; 27 } 28 } 29 } 30 }
浅克隆与深克隆的区别
1.浅克隆:一个原型对象中的成员变量如果只为值类型,在调用它时,将复制一份给克隆对象。如果成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,当改变克隆对象的成员变量时,值类型会发生改变。如:成员变量int i=0; 现在克隆对象将 i=1;那么的到的结果也为1。当改变引用类型变量时,则不会发生变化。
2.深克隆:无论该原型对象的成员变量时值类型还是引用类型,调用时都将复制一份给克隆对象。当改变成员变量时,不管是值类型还是引用类型都将发生变化。