今天学习了原型模式,在这里记下来:
工作中,很多时候要复制一个方法,或什么的?如果直用CTRL_V,那样太麻烦了,还不能改,下面做一个浅复制的原型模式!
代码如下:先定义一个类:
View Code
//定义一个个人简历类,继承ICloneable 这个接口,这个接口可以帮我们复制 public class Resume : ICloneable { //定义一些个人信息 private string name; private string sex; private string age; private string timearea; private string company; public Resume(string name) { this.name = name; } /// <summary> /// 设置个人信息 /// </summary> /// <param name="sex"></param> /// <param name="age"></param> public void Setpersonalinfo(string sex, string age) { this.sex = sex; this.age = age; } /// <summary> /// 设置工作经历 /// </summary> /// <param name="timearea"></param> /// <param name="company"></param> public void SetWorkExperience(string timearea, string company) { this.timearea = timearea; this.company = company; } /// <summary> /// 显示 /// </summary> public void Display() { Console.WriteLine("{0} {1} {2}", name, sex, age); Console.WriteLine("工作经历:{0},{1}", timearea, company); } //实现ICloneable这个接口返回一个浅表副本 public Object Clone() { return (Object)this.MemberwiseClone(); } }
这个类定义完了之后,然后我们在控制台来调用,代码如下:
View Code
class Program { static void Main(string[] args) { //创建第一个对象 Resume a= new Resume("小何"); a.Setpersonalinfo("男","25"); a.SetWorkExperience("1999", "xxx公司"); //创建第二个对象,浅复制第一个对象 Resume b = (Resume)a.Clone(); //创建第三个对象,浅复制第一个对象 Resume c = (Resume)a.Clone(); //再修改工作经历这个方法 c.SetWorkExperience("1999-3000", "新浪公司"); //输出这三个对象的结果 a.Display(); b.Display(); c.Display(); Console.ReadKey(); } }
输出结果果如下:
这样就可以看得清清楚楚了,我们只创建了一个对象,然后可以直接复制这个对象,同时还可以做一些修改。
这样以后写代码如果有这样的情况,就可以直接使用,原型模式了!方便强大!
刚刚上面原型模式是一个浅复制的原型模式,我们都是复制类中的字符串属性,但如果这些属性是从外面类中传过来,
这时,这个原型模式得到结果就是不是上面那样的,它得到的三个对象结果都会一样,都只是最后一个对象的结果同。
为什么会这样呢,因为我们上面这个浅复制,如果是字符串值类型,是可以浅复制的,但如果是一个引用类型就会不一样了!
那我们现在把刚才的代码改下,做一个深复制的原理模式!
我们这次加一个工作经历类:我们在这个类中也继承ICloneable这个接口,然后重写这个接口!
代码:
View Code
/// <summary> /// 工作经历类 /// </summary> public class WorkExperience:ICloneable { private string workdate; public string Workdate { get { return workdate; } set { workdate = value; } } private string company; public string Company { get { return company; } set { company = value; } } #region ICloneable 成员 public object Clone() { return (object)this.MemberwiseClone(); } #endregion }
这个类写完了以后,我们再写一个工作经历类,
代码
View Code
//定义一个个人简历类,继承ICloneable 这个接口,这个接口可以帮我们复制 public class Resume : ICloneable { //定义一些个人信息 private string name; private string sex; private string age; //声明一个工作经历类 public WorkExperience work; //定义一个外部的构造函数 public Resume(string name) { this.name = name; work = new WorkExperience(); } //定义一个内部的构造函数,传一个工作经历类过来 private Resume(WorkExperience work) { //提供Clone方法调用私有的构造函数,以便克隆“工作经历”的数据 this.work = (WorkExperience)work.Clone(); } /// <summary> /// 设置个人信息 /// </summary> /// <param name="sex"></param> /// <param name="age"></param> public void Setpersonalinfo(string sex, string age) { this.sex = sex; this.age = age; } /// <summary> /// 设置工作经历 /// </summary> /// <param name="timearea"></param> /// <param name="company"></param> public void SetWorkExperience(string timearea, string company) { work.Workdate = timearea; work.Company = company; } /// <summary> /// 显示 /// </summary> public void Display() { Console.WriteLine("{0} {1} {2}", name, sex, age); Console.WriteLine("工作经历:{0},{1}",work .Workdate ,work .Company ); } //实现ICloneable这个接口 public Object Clone() { //调用私有的构造方法,让“工作经历”克隆完成然后再给这个“简历”对象的相关字段赋值,最终返回一个深复制的简历对象 Resume obj = new Resume(this.work ); obj.name = this.name; obj.sex = this.sex; obj.age = this.age; return obj; } }
然后在控制台调用
View Code
static void Main(string[] args) { //创建第一个对象 Resume a= new Resume("小何"); a.Setpersonalinfo("男","25"); a.SetWorkExperience("1999", "xxx公司"); //创建第二个对象,浅复制第一个对象 Resume b = (Resume)a.Clone(); //创建第三个对象,浅复制第一个对象 Resume c = (Resume)a.Clone(); //再修改工作经历这个方法 c.SetWorkExperience("1999-3000", "新浪公司"); //输出这三个对象的结果 a.Display(); b.Display(); c.Display(); Console.ReadKey(); }
结果:
这样结果也是一样了,现在深复制原型模式和浅原型模式都做完了,以后哪种情况下都可以很好的用了!