zl程序教程

您现在的位置是:首页 >  后端

当前栏目

设计模式之原型模式

2023-09-14 08:56:49 时间

小菜的问题:要把简历发到多家公司,简历的份数就必须足够。

大鸟的回答:用编程来复制自己简历。

二.解决过程

① 最初的写法:

 简历类:

 span class Resume

 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);

 /span 
客户端调用代码:

 span static void Main(string[] args)

 Resume a = new Resume("大鸟");

 a.SetPersonalInfo("男", "29");

 a.SetWorkExperience("1998-2000", "XX公司");

 Resume b = new Resume("大鸟");

 b.SetPersonalInfo("男", "29");

 b.SetWorkExperience("1998-2000", "XX公司");

 Resume c = new Resume("大鸟");

 c.SetPersonalInfo("男", "29");

 c.SetWorkExperience("1998-2000", "XX公司");

 a.Display();

 b.Display();

 c.Display();

 Console.Read();

 } /span 
这样,确实可以做到复制出多份简历,但想要修改简历,每一个实例化的简历都需要修改。这样的工作就很庞大了。

② 传引用写法:

 span static void Main(string[] args)

 Resume a = new Resume("大鸟");

 a.SetPersonalInfo("男", "29");

 a.SetWorkExperience("1998-2000", "XX公司");

 Resume b = a;

 Resume c = a;

 a.Display();

 b.Display();

 c.Display();

 Console.Read();

 } /span 

这样,代码虽然简单了,但根本没有做到复制简历,b和c纸张上无法将a上的内容得到。

原型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

创建原型类:

 span abstract class Prototype 

 private string id;

 public Prototype(string id)

 this.id = id;

 public string Id

 get { return id; }

 public abstract Prototype Clone();//抽象类的关键方法Clone

 } /span 
具体原型类:

 span class ConcretePrototype1 : Prototype 

 public ConcretePrototype1(string id)

 : base(id)

 public override Prototype Clone()

 return (Prototype)this.MemberwiseClone();

 /span 
客户端代码:

 span static void Main(string[] args)

 ConcretePrototype1 p1 = new ConcretePrototype1("I");

 ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();

 Console.WriteLine("Cloned:{0}", c1.Id);

 Console.Read();

 } /span 
利用ICloneable接口实现简历原型:

简历类:

 span 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();

 span /span } /span 
客户端代码:

 span 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", "XX公司");

 Resume c = (Resume)a.Clone();

 c.SetWorkExperience("男", "24");

 a.Display();

 b.Display();

 c.Display();

 Console.Read();

 /span 

① 浅复制:

被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。这样的定义很难理解,就拿实例结果说话吧:

原本想要前图那样的效果,结果却是后图。这样一个过程也就是浅复制的过程,看似复制了,但实际上内容并没有得到复制。

② 深复制:

把引用对象的变量指向复制过的新对象,而不是原有的被引用的对象。

工作经历类:

 span class WorkExperience:ICloneable //让“工作经历”实现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; }

 public Object Clone()

 return (Object)this.MemberwiseClone();//“工作经历”类实现克隆方法

 } /span 
简历类:

 span private Resume(WorkExperience work)

 this.work = (WorkExperience)work.Clone();//提供Clone方法调用的私有构造函数,以便克隆“工作经历”的数据

 } /span 


 span public Object Clone()

 Resume obj = new Resume(this.work);//调用私有的构造方法,让“工作经历”克隆完成,然后再给“简历”对象的相关字段赋值

 obj.name = this.name;

 obj.sex = this.sex;

 obj.age = this.age;

 return obj;

 } /span 
从而达到我们想要的结果,如下图:



五.学习心得

对于这一过程的学习,觉得原型模式很简单,生活中也很常见,只要给出一个原型的种类就行。复制简历,是一个很常见的实例,运用原型模式,也确实是最佳体现。至于后面的浅复制与深复制的学习,刚开始不知道他们想表达的是什么意思,于是从结果出发,浅复制的结果不是所想要得到的,深复制才是,这时候便去研究两者的代码,两者的结构图,才发现,其实也很简单,只要将“工作经历”这一类同样利用接口去实现,就可以达到其想要达到的效果了。








设计模式 | 原型模式 原型模式作为一种快速创建大量相同或相似对象的方式,在软件开发中的应用较为泛,很多软件提供的复制(`Ctrl+C`)和粘贴(`Ctrl+V`)操作就是原型模式的典型应用。
设计模式-14-原型模式 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。也属于创建型模式。就是使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。
设计模式】C#实现原型模式 用于创建重复的对象,但又不希望外部出现很多new,又能保证性能。 如果对象的创建成本比较大,例如某个对象里面的数据需要访问数据库才能拿到;并且同一个类的不同对象之间差别不大(大部分字段都相同),这种场景下可以考虑使用原型模式达到提高程序性能的作用。
原型模式属于创建型模式,用原型的实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。调用者不需要关注具体的复制过程,而且不需要知道任何创建的细节,通俗来讲,就是使用一个对象复制一个一模一样的对象出来,目的就是保护最原始的那一份存档。