原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道创建的细节
UML图:
实现:
//原型类
abstract class Prototype
{
private string id;
public Prototype(string id)
{
this.id = id;
}
public string ID {
get { return id; }
}
public abstract Prototype Clone();
}
//具体原型类
class ConcretePrototype1 : Prototype
{
//提供与父类构造函数参数相同的构造函数
public ConcretePrototype1(string id) : base(id)
{
}
public override Prototype Clone()
{
//创建当前对象的浅表副本。方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此原始对象及其副本应用同一对象[MSDN]
return (Prototype)this.MemberwiseClone();
}
}
//客户端
static void Main(string[] args) {
ConcretePrototype1 p1 = new ConcretePrototype1("Ayosi");
ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();
Console.WriteLine("Clone: {0}", c1.ID);
Console.Read();
}
.Net在System命名空间中提供了ICloneable接口,这个接口中维一的方法是Clone(),实现这个接口即可完成原型模式。
深度复制:
对于深拷贝和浅拷贝的解析:C#进阶系列
UML:
实现
class WorkExperience : ICloneable
{
public string WorkDate {
get;
set;
}
public string Company {
get;
set;
}
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)
{
//提供Clone方法调用的私有构造函数,以便克隆“工作经历”的数据
this.work = (WorkExperience)work.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 object Clone()
{
//调用私有的构造方法,让“工作经历”克隆完成,然后再给这个“简历”对象的相关字段赋值,最终返回一个深复制的简历对象
Resume obj = new Resume(this.work);
obj.name = this.name;
obj.sex = this.sex;
obj.age = this.age;
return obj;
}
}
浅表复制是只能拷贝当前层中的值类型数据,对于更深层的数据需要在更深层出实现ICloneable接口
参考:
[1] 大话设计模式,程杰