用原型实例制定创建对象的种类,并通过拷贝这些原型,创建新的对象。
就是从一个对象在创建另一个可定制的对象,而且不需要知道任何创建的细节。
(1)、实现Cloneable接口,可以使用此接口的类上使用clone方法。
(2)、重写Object类中的clone方法,因为所有类的父类是Object类,Object有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此,将clone改为public类型。
代码实现:
class Resume : ICloneable//实现ICloneable接口 { private string name; private string computer; public Resume(string name) { this.name = name; } public void SetWordExperience(string computer) { this.computer = computer; } public void Display() { Console.WriteLine("{0}", name); Console.WriteLine("工作经历: {0}", computer); } public Object Clone()//重写Clone方法,改为public类型 { return (Object)this.MemberwiseClone(); } }
客户端代码:
class Program { static void Main(string[] args) { Resume a = new Resume("大鸟"); a.SetWordExperience("XX大公司"); a.Display(); for (int i = 0; i < 3; i++)//没有别的意思,只是用用 { Resume _i = (Resume)a.Clone(); _i.SetWordExperience("YY大公司"); _i.Display(); } Console.Read(); } }
Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝。
这里指谈谈引用对象的深复制:
需要解决的代码:
class WrokExperience//新加入一个类 { private string workDate; public string WorkDate { get { return workDate; } set { workDate = value; } } } class Resume : ICloneable { private string name; private string computer; private WrokExperience work;//引用类 public Resume(string name) { this.name = name; work = new WrokExperience(); } public void SetWorkExperience(string computer, string workDate) { this.computer = computer; work.WorkDate = workDate; } public void Display() { Console.WriteLine("{0}", name); Console.WriteLine("工作经历: {0} {1}", work.WorkDate, computer);//这里的WorkDate ,需要的是每一次赋值的。 } public object Clone() { return (Object)this.MemberwiseClone(); } } class Program { static void Main(string[] args) { Resume a = new Resume("大鸟"); a.SetWorkExperience("1998-2008", "XX大公司"); Resume _i = (Resume)a.Clone(); _i.SetWorkExperience("1997-2008", "YY大公司"); Resume b = (Resume)a.Clone(); b.SetWorkExperience("1996-2008", "ZZ大公司"); a.Display(); _i.Display(); b.Display(); Console.Read(); } }
而实际上,我们需要的是不一样的。
修改代码:
class WorkExperience : ICloneable//对于引用类同样的拷贝 { private string workDate; public string WorkDate { get { return workDate; } set { workDate = value; } } public Object Clone() { return (Object)this.MemberwiseClone(); } } class Resume : ICloneable { private WorkExperience work; private string name; private string computer; public Resume(string name) { this.name = name; work = new WorkExperience(); } private Resume(WorkExperience work)//做了一个私有的构造方法,让它克隆完成,然后再给这个”简历“对象的响应字段赋值,最终返回一个深复制的简历对象 { this.work = (WorkExperience)work.Clone(); } public void SetExperience(string workDate, string computer) { work.WorkDate = workDate; this.computer = computer; } public void Display() { Console.WriteLine("{0}", name); Console.WriteLine("工作经历: {0} {1}", work.WorkDate, computer); } public Object Clone() { Resume obj = new Resume(this.work); obj.name = this.name; obj.computer = computer; return obj; } }
运行结果:
得到预期结果。
其实,我们使用原型模式,简单的说我们就是简化对象的创建。