原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
即:就是从一个对象再创建另外一个可定制的对象,而且不需知道任何创建的细节。就是克隆一个新的对象,在客户端,看不到简历类的内容。但是可以修改细节。
实例:写简历。我们简单设置个人信息和工作经历不同的两个新情况。
简历类:
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();
}
}
客户端:
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");
a.Display();
b.Display();
c.Display();
Console.Read();
}
结果:
分析:只需要调用Clone方法就可以实现新简历的生成,并且可以再修改新简历的细节。 一般在初始化的信息不发生变化的情况下,克隆是最好的办法。这既隐藏了对象创建的细节,又对性能是大大的提高。克隆不用重新初始化对象,而是动态地获得对象运行时的状态。
浅复制与深复制:
我认为浅复制就相当于对一个东西的操作。深复制就是复制一个新东西,对它进行操作。举例:浅复制就是对于一个种子,栽种浇水。深复制是克隆出新的种子,对它进行栽种浇水各种操作,原来的种子不受影响。
简历浅复制的实现:
代码:
工作经历类:
//工作经历
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();
}
}
客户端调用代码:
class Program
{
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");
a.SetWorkExperience("1998~2003", "zz企业");
a.Display();
b.Display();
c.Display();
Console.Read();
}
}
分析:对于值类型name,sex,age,当客户端对其进行修改时,会发生改变。但是对于引用类型,如work.Date,work.Company只是复制了引用,并不是复制了实体,所以一直是对于原始对象进行修改。于是三次展示的都是最后修改的结果。
简历深复制的实现:
工作经历类中,增加了克隆这个方法。
public Object Clone()
{
return (Object)this.MemberwiseClone();
}
简历类中提供Clone方法调用的私有构造函数,以便克隆“工作经历”的数据。
private Resume(WorkExperience work)
{
this.work = (WorkExperience)work.Clone();
}
简历类调用私有的构造方法,让“工作经历”克隆完成,然后再给这个“简历”对象的相关字段赋值,最终返回一个深复制的简历对象。
public object Clone()
{
Resume obj = new Resume(this.work);
obj.name = this.name;
obj.sex = this.sex;
obj.age = this.age;
return obj;
}
结果,三次的显示结构各不同:
分析:
这样是分别克隆出几个实体,进行修改,所以三种呈现的不同的结果。