原型模式(Prototype),用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象[DP]。
“原型模式其实就是从一个对象再创建另外一个可定制的对象,而不需要知道任何创建的细节。”
基础知识this.MemberwiseClone(),MSDN解释:创建对象的浅表副本。方法是创建一个新的对象,然后将该对象的非静态字段复制到该新对象。如果字段是值类型,则对字段执行逐位复制。如果对象是引用类型则复制引用而不复制引用的对象;因此原始对象和副本引用一个对象。
在.NET在System命名空间提供了ICloneable接口,其中的唯一一个方法Clone()这样只需实现这个接口就可以完成原型模型了。
所以在使用Clone方法时候一定要注意属性是值类型还是引用类型。
值类型原型模式:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 namespace Pattern.Prototype.ValueTypeClone 2 { 3 class Resume : ICloneable 4 { 5 private string Name { get; set; } 6 private string Sex { get; set; } 7 private string Age { get; set; } 8 private string TimeArea { get; set; } 9 private string Company { get; set; } 10 public Resume(string name) 11 { 12 this.Name = name; 13 } 14 public void SetPersinalInfo(string age, string sex) 15 { 16 this.Sex = sex; 17 this.Age = age; 18 } 19 public void SetWorkExprience(string timeArea, string company) 20 { 21 this.TimeArea = timeArea; 22 this.Company = company; 23 } 24 public void Display() 25 { 26 Console.WriteLine("{0} {1} {2}",Name,Sex,Age); 27 Console.WriteLine("工作经历{0} {1}",TimeArea,Company); 28 } 29 public object Clone() 30 { 31 return (object)this.MemberwiseClone(); 32 } 33 } 34 }
属性为值类型不存在复制问题。
引用类型原型浅度Clone问题:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 namespace Pattern.Prototype.ReferenceClone 2 { 3 class WorkExperience 4 { 5 public string Time { get; set; } 6 public String Company { get; set; } 7 } 8 9 class Resume : ICloneable 10 { 11 private string Name { get; set; } 12 private string Sex { get; set; } 13 private string Age { get; set; } 14 15 WorkExperience WorkExprience { get; set; } 16 17 public Resume(string name) 18 { 19 this.Name = name; 20 this.WorkExprience = new WorkExperience(); 21 } 22 public void SetPersinalInfo(string age, string sex) 23 { 24 this.Sex = sex; 25 this.Age = age; 26 } 27 public void SetWorkExprience(string timeArea, string company) 28 { 29 this.WorkExprience.Time = timeArea; 30 this.WorkExprience.Company = company; 31 } 32 public void Display() 33 { 34 Console.WriteLine("{0} {1} {2}", Name, Sex, Age); 35 Console.WriteLine("工作经历{0} {1}", WorkExprience.Time, WorkExprience.Company); 36 } 37 public object Clone() 38 { 39 return (object)this.MemberwiseClone(); 40 } 41 } 42 }
只Clone引用,不能个性化使用属性。
引用类型自定义一级深度复制:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 namespace Pattern.Prototype.DeepClone 2 { 3 class WorkExperience 4 { 5 public string Time { get; set; } 6 public String Company { get; set; } 7 } 8 9 class Resume : ICloneable 10 { 11 private string Name { get; set; } 12 private string Sex { get; set; } 13 private string Age { get; set; } 14 15 WorkExperience Work { get; set; } 16 17 public Resume(string name) 18 { 19 this.Name = name; 20 this.Work = new WorkExperience(); 21 } 22 /// <summary> 23 /// 提供自的定深度复制的私有构造函数 24 /// </summary> 25 /// <param name="experience"></param> 26 private Resume(WorkExperience experience) 27 { 28 this.Work = (WorkExperience)this.Clone(); 29 } 30 public void SetPersinalInfo(string age, string sex) 31 { 32 this.Sex = sex; 33 this.Age = age; 34 } 35 public void SetWorkExprience(string timeArea, string company) 36 { 37 this.Work.Time = timeArea; 38 this.Work.Company = company; 39 } 40 public void Display() 41 { 42 Console.WriteLine("{0} {1} {2}", Name, Sex, Age); 43 Console.WriteLine("工作经历{0} {1}", Work.Time, Work.Company); 44 } 45 /// <summary> 46 /// 只复制一层的深度复制 47 /// </summary> 48 /// <returns></returns> 49 public object Clone() 50 { 51 Resume obj = new Resume(this.Name); 52 obj.Work.Time = this.Work.Time; 53 obj.Work.Company = this.Work.Company; 54 obj.Age = this.Age; 55 obj.Sex = this.Sex; 56 return obj; 57 } 58 } 59 }
深度Clone一层对象,可以自定义设置属性。