原型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
小编今天讲讲原型模式的核心:深复制与浅复制
浅复制:复制地址和地址指向的对象
举例:2复制了1的地址之后依然指向a,也就是说1和2都指向a
如果2在复制的过程中把a的值改成了b,那1地址指向的值也变成了b
如果3在复制的过程中把b改成了c,那现在1,2,3都指向c
深复制:只复制地址
当2复制的时候自己创建新的对象b,不会更改a,所以1仍然指向a
当3复制的时候也会创建自己的对象c,不会更改a和b,1仍然指向a,2仍然指向b
看代码:
浅复制:
//简历类
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 wordDate, string company) //调用此方法时,给对象的两属性赋值。
{
Work.WorkDate = wordDate;
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 WorkExperience: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();
}
}
深复制:
// 简历类
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)
{
this.work = (WorkExperience)work.Clone();//提供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;
}
}
客户端调用都是:
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");
c.SetWorkExperience("1998-2003", "zz企业");
a.Display();
b.Display();
c.Display();
Console.Read();
}
浅复制克隆过程中克隆了a的信息,但是b,c克隆a的信息后,时间和企业都被更改,因为a,b,c都指向同一个对象,所以最终显示a,b,c的结果是相同的:
深复制中用构造方法的重载,在克隆过程中创建新的对象,这样就可以使复制的地址指向自己新创建的对象了,所以他们的结果是不同的:
public Resume(string name)
{
this.name = name;
work = new WorkExperience();
}
private Resume(WorkExperience work)
{
this.work = (WorkExperience)work.Clone();//提供clone方法调用的私有构造函数,以便克隆工作经历的数据。
}
其实并不难,你懂了吗