标签:
原型模式就是从一个对象再创建另一个可定制的对象,而不需要知道任何创建的细节。
原型模式本身是比较简单的,不过其中牵涉到浅复制和深复制的实现,下面使用.Net自带的方法和接口分别实现浅复制和深复制:
public class WorkExperience : ICloneable
{
public string workDate;
public string experience;
#region ICloneable 成员
public object Clone()
{
//浅复制
return this.MemberwiseClone();
}
#endregion
}
MemberwiseClone方法实现的是浅复制,即如果字段是值类型,则对该字段执行逐位复制,如果字段是引用类型,则复制引用但不复制引用的对象,因此,原是对象及其复本引用的是同一对象。不过,经过测试发现,对string类型的执行的复制与值类型是相同的,修改新变量中string的值不会影响原变量的值测试如下:
WorkExperience we = new WorkExperience(); we.workDate="today"; we.experience="test";
//输出为work experience: today, test Console.WriteLine("work experience: {0},{1}", we.workDate, e.experience); WorkExperience we2 = (WorkExperience)we.Clone(); we2.experience = "test2"; we2.workDate = "tomorrow";
//输出为work experience: tomorrow,test2 Console.WriteLine("work experience: {0},{1}", we2.workDate, e2.experience);
//输出为work experience: today, test
Console.WriteLine("work experience: {0},{1}", we.workDate, we.experience);
下面演示如何进行深复制和浅复制:
public class Resume : ICloneable
{
public string name;
//引用类型,需要区分深复制和浅复制
public WorkExperience workExperience;
public Resume(string name)
{
this.name = name;
workExperience = new WorkExperience();
}
public void SetExperience(string workDate, string experience)
{
workExperience.workDate=workDate;
workExperience.experience=experience;
}
public void Show()
{
Console.WriteLine("name : {0}",name);
Console.WriteLine("work experience: {0},{1}",workExperience.workDate,workExperience.experience);
}
/// <summary>
/// 提供一个私有构造函数,供复制方法使用,以便复制WorkExperience的数据
/// </summary>
/// <param name="workExperience"></param>
private Resume(WorkExperience workExperience)
{
this.workExperience = (WorkExperience)workExperience.Clone();
}
#region ICloneable 成员
/// <summary>
///深复制,实例化一个新的对象
/// </summary>
/// <returns></returns>
public object Clone()
{
Resume newResume = new Resume(this.workExperience);
newResume.name = this.name;
return newResume;
}
/// <summary>
/// 浅复制
/// </summary>
/// <returns></returns>
public object Copy()
{
return this.MemberwiseClone();
}
#endregion
}
上例中Clone和Copy分别实现了深复制和浅复制,测试如下:
Resume myResume = new Resume("Kelly");
myResume.SetExperience("2004-2008", "University");
myResume.Show();
//使用浅复制,更改WorkExperience,则被复制对象也被更改
Resume newResume = (Resume)myResume.Copy();
newResume.SetExperience("2008-2012", "Master Degree");
newResume.name = "Mike";
myResume.Show();
//使用深复制,更改WorkExperience,被复制对象不会被更改
Resume newResume2 = (Resume)myResume.Clone();
newResume2.SetExperience("2012-now", "Company");
newResume2.name = "Jack";
myResume.Show();
运行结果为:
name : Kelly
work experience: 2004-2008,University
name : Kelly
work experience: 2008-2012,Master Degree
name : Kelly
work experience: 2008-2012,Master Degree
可以看出,name由于是string类型,所以始终不会被修改,work experience是引用类型,在第一次做浅复制后被修改,第二次做深复制后没有被修改。
一般在初始化信息不发生变化的情况下,克隆是最好的办法,这即隐藏了对象创建的细节,又对性能有很大的提高。
标签:
原文地址:http://www.cnblogs.com/angela217/p/5405031.html