> 文档中心 > 【原型模式】简历复印

【原型模式】简历复印

文章目录

  • 原型模式
      • 原型模式:
      • 结构图:
      • 代码:
  • 简历的原型实现
      • 结构图
      • 代码:
  • 浅复制和深复制
      • 结构图:
      • 代码
        • 浅复制:
        • 深复制:

原型模式

针对简历的复印,并不简单地复制黏贴,如果有需要改动的地方,那么就需要改动很多的地方。

原型模式:

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

结构图:

在这里插入图片描述

代码:

原型类:

 abstract class Prototype    { private string id;  public Prototype (string id) {     this.id = id; } public string Id {     //获取内容     get { return id; } } ///  /// 抽象类的关键就是有这样一个Clone方法 ///  ///  public abstract Prototype Clone();    }

具体原型类

 class ConcretePrototype1:Prototype     { public ConcretePrototype1(string id):base(id) { } ///  /// 创建当前对象的浅表副本。方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。 /// 如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象, /// 因此,原始对象及其副本引用同一个对象。 ///  ///  public override Prototype Clone() {     //创建浅表副本     return (Prototype)this.MemberwiseClone(); }    }

客户端代码

   class Program    { static void Main(string[] args) {     ConcretePrototype1 p1 = new ConcretePrototype1("I");     //克隆类ConcretePrototype1的对象,p1就能得到新的实例c1     ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();     Console.WriteLine("Cloned:{0}", c1.Id);     Console.Read();   }    }

简历的原型实现

一般在初始化的信息不发生变化的情况下表,克隆是最好的方法,这既隐藏了对象创建的细节,又对性能大大的提高,它等于是不用重新初始化对象,而是动态地获得对象运行时的状态。

结构图

在这里插入图片描述

代码:

简历类:

//简历    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; } //设置个人信息   public void SetPersonalInfo(string sex, string age) {     this.sex = sex;     this.age = age; } //设置工作经历 public void SetWorkExperience(string timeArea, string company) {     this.timeArea = timeArea;     this.company = company; } //显示 public void Display() {     Console.WriteLine("{0}  {1}  {2}", name, sex, age);     //实现接口的方法,用来克隆方法     Console.WriteLine("工作经历:{0}  {1} ", timeArea, company); } public Object Clone() {     return (object)this.MemberwiseClone(); }    }

客户端代码

 class Program    { static void Main(string[] args) {     Resume a = new Resume("大鸟");     a.SetPersonalInfo("男", "29");     a.SetWorkExperience("1998-2000", "XX公司");     //只需要调用Clone方法就可以实现新简历的生成,并且可以再修改新简历的细节     Resume b = (Resume)a.Clone();     b.SetWorkExperience("1998-2006", "XX企业");     Resume c = (Resume)a.Clone();     c.SetPersonalInfo("男", "24");     a.Display();     b.Display();     c.Display();     Console.Read(); }    }

浅复制和深复制

MemberwiseClone()方法的使用:如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象,因此,原始对象及其复本引用同一对象。

结构图:

浅复制:
在这里插入图片描述
深复制:
在这里插入图片描述

代码

浅复制:

工作经历类

   ///     /// 工作经历    ///     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; //引用“工作经历”对象 //work是引用类型 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(); }    }

客户端代码

class Program    { static void Main(string[] args) {     Resume a = new Resume("大鸟");     a.SetPersonalInfo("男", "29");     a.SetWorkExperience("1988-2000", "XX公司");     //b和c都克隆于a,但当他们都设置了“工作经历”时,我们希望的结果是三个的显示不一样。     //但是结果是三个结果是一样的,这里是应用了浅复制,对比一下深复制。     Resume b = (Resume)a.Clone();     b.SetWorkExperience("1998-2000", "YY公司");     Resume c = (Resume)a.Clone();     c.SetPersonalInfo("男", "24");     c.SetWorkExperience("199-2000", "ZZ公司");     a.Display();     b.Display();     c.Display();     Console.Read(); }    }

深复制:

工作经历

 ///     /// 工作经历    ///     /// 让工作经历类实现ICloneable接口    class WorkExperience :ICloneable     { private string workDate; private string WorkDate {     get { return workDate; }     set { workDate = value; } } private string company; public string Company {     get { return company; }     set { company = value; } } ///  /// 让工作经历类实现克隆方法 ///  ///  public Object Clone() {     return (Object)this.MemberwiseClone(); }    }

简历类

     ///     /// 简历类    ///     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(); } private Resume (WorkExperience work ) {     //提供Clone方法调用的私有构造函数,以便克隆“工作经历”的数据     this.work = (WorkExperience)work.Clone(); } //设置个人信息 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() {     //调用私有的构造函数,让后工作经历克隆完成,然后再给这个简历对象的相关字段赋值,最终返回一个深复制的简历对象。     //最终得到了希望的三个不一样的结果。     Resume obj = new Resume(this.work);     obj.name = this.name;     obj.sex = this.sex;     obj.age = this.age;     return obj; }    }

浅表复制,对于值类型,没有问题,但是对于引用类型,只是复制了引用,对引用的对象还是指向了原来的对象,所以,上面的给abc三个引用设置了不同的工作经历,但是却同时看到了三个引用都是最后一次的设置,这是因为这三个引用都指向了同一个对象。这个是浅复制。(被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。)

如果我们的需求是把要复制的对象所引用的对象都复制一遍,那么就是用深复制,深复制就是把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。

涉及深复制或者浅复制,数据集对象DataSet,它就有Clone()方法和Copy()方法,clone()方法用来复制DataSet的结果,但不复制DataSet的数据,实现了原型模式的浅复制,copy方法不但复制结构也复制数据,实现了原型模式的深复制。

编程是一门技术,大批量的改动,是一件非常丑陋的做法。 WIFI共享精灵