标签:设计模式
设计模式这本书通过对小菜求职复印简历,给我们引出了原型模式:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象。其实说简单点就是我们创建好一个模板,然后进行复制,或者将模板修改后进行制……
由于MemberwiseClone()方法对于字段为值类型的,则对该字段执行逐位复制;如果字段是引用类型,则复制引用但不复制引用的对象,因此原始对象及其复本引用同一对象。所以我们把复制分为浅复制和深复制!
浅复制:被复制对象的所有变量都含有与原来的对象相同的值,而其所有的对其他对象的引用都仍然指向原来的对象。
解释:一个对象中的字段有的是值类型的,有的是引用类型的。对于值类型字段来说,它的值就是简单的值,而对于引用类型来说,它的值是地址。浅复制在复制时,就是将这个对象的值字段和引用字段全部复制过去,、获得了这个对象的值和地址。所以当一个对象的引用字段所指向的地址中的变量变化时,所有浅复制对象中的该引用字段都会发生变化。
<span style="font-size:18px;">class Program { //工作经历 class WorkExperience { private string workDate; public string WorkDate { get { return workDate ; } set { workDate = value; } } private string company; public string Company { get { return company; } set { company = value; } } } //简历 class Resume : ICloneable { private string name; private string sex; private string age; private WorkExperience work;//引用“工作经历”对象 public Resume(string name) { this.name = name;//在“简历”实例化时同时实例化“工作经历” work = new WorkExperience(); } //设置个人信息 public void SetPersonalInfo(string sex, string age) { this.sex = sex; this.age = age; } //设置工作经历 public void SetWorkExperience(string workDate, string company) { work.WorkDate = workDate;//调用此方法的时候给对象的两个属性赋值 work.Company = company; } //显示 public void Display() { Console.WriteLine("{0} {1} {2}", name, sex, age); Console.WriteLine("工作经历: {0} {1} ", work.WorkDate , work.Company ); } public Object Clone() { return (object)this.MemberwiseClone(); } static void Main(string[] args) { Resume a = new Resume("大鸟"); a.SetPersonalInfo("男", "29"); a.SetWorkExperience("1998-2000", "xx公司"); Resume b = (Resume)a.Clone(); b.SetWorkExperience("1998-2006", "yy企业"); Resume c = (Resume)a.Clone(); c.SetPersonalInfo("男", "24"); c.SetWorkExperience("1998-2003", "zz企业"); a.Display(); b.Display(); c.Display(); Console.Read(); } } </span>
我们在“简历”类中设计了一个“设置工作经历”的方法,然后又设计了一个“工作经历”的类,“简历”类直接调用“工作经历”类中的对象。由于这是引用类型,当b和c克隆于a时只是复制了引用,对引用的对象还是指向了原来的对象,所以结果是看到三个引用都是最后一次的设置,因为三个引用都指向了同一个对象。就是a中的引用类型的内容没有复制给b和c,所以b和c都要指向a中的那个部分。
深复制:把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。
解释:被复制对象会将所有非引用类型的字段复制给新对象,同时将引用类型指向地址中存的对象复制给新对象。
<span style="font-size:18px;">class Program { //工作经历 class WorkExperience { private string workDate; public string WorkDate { get { return workDate ; } set { workDate = value; } } private string company; public string Company { get { return company; } set { company = value; } } } //简历 class Resume : ICloneable { private string name; private string sex; private string age; private WorkExperience work;//引用“工作经历”对象 public Resume(string name) { this.name = name;//在“简历”实例化时同时实例化“工作经历” work = new WorkExperience(); } //设置个人信息 public void SetPersonalInfo(string sex, string age) { this.sex = sex; this.age = age; } //设置工作经历 public void SetWorkExperience(string workDate, string company) { work.WorkDate = workDate;//调用此方法的时候给对象的两个属性赋值 work.Company = company; } //显示 public void Display() { Console.WriteLine("{0} {1} {2}", name, sex, age); Console.WriteLine("工作经历: {0} {1} ", work.WorkDate , work.Company ); } public Object Clone() { return (object)this.MemberwiseClone(); } static void Main(string[] args) { Resume a = new Resume("大鸟"); a.SetPersonalInfo("男", "29"); a.SetWorkExperience("1998-2000", "xx公司"); Resume b = (Resume)a.Clone(); b.SetWorkExperience("1998-2006", "yy企业"); Resume c = (Resume)a.Clone(); c.SetPersonalInfo("男", "24"); c.SetWorkExperience("1998-2003", "zz企业"); a.Display(); b.Display(); c.Display(); Console.Read(); } } </span>
“简历“和”工作经历“两个类都要实现克隆接口,在”简历“类中引用一个”工作经历“对象work,然后在”简历“实现克隆方法时调用私有的构造函数,让”工作经历“克隆完成,再进行对象的相关字段赋值。说白了深复制就是”简历“先把”工作经历“中的东西复制过来,所以a中的“工作经历”就不是引用类型,所以在复制给b和c的时候可以直接给复制过去。然后再对b和c进行赋值,就完成了深复制。
刚开始时,对深复制和浅复制很晕,后来和同学讨论后觉得应该这么理解……如果不对,还请大神来解救!
标签:设计模式
原文地址:http://blog.csdn.net/xingyu0806/article/details/43851181