您的位置:首页 > 其它

设计模式——原型模式(Prototype patterns)

2008-08-23 18:09 471 查看
[align=left]设计模式(6):原型模式(Prototype patterns)[/align]

[align=left] [/align]

[align=center]原型模式(Prototype patterns)[/align]

[align=center] [/align]

[align=left][b]动机[/b][/align]

[align=left] 在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出“这些易变对象”从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变. [/align]

[align=left] [/align]

[align=left][b][b][b]意图[/b][/b][/b][/align]

[align=left] 使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。[/align]

[align=left].NET在System命名空间中提供了ICloneable接口,其中就有唯一的一个方法Clone(),这样就只需要实现这个接口就可以完成原型模式了[/align]

[align=left] [/align]

[align=center]原型模式(Prototype patterns)结构图[/align]

[align=center][/align]



[align=center][b]简历的原型实现[/b][/align]

[align=center][/align]






[align=center][/align]



[align=center][/align]

简历类:

class Resume

{

private string name;

private string sex;

private string age;

private string tiemArea;

private string company;

public Resume(string name)

{

this.name=name;

}

public void setPersonalnfo(string sex,string age)

{

this.sex=sex;

this.age=age;

}

public void SetWorkExperience(string tiemArea,string company)

{

this.tiemArea=tiemArea;

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();

}

}

[align=left] [/align]

[align=left]客户端代码:[/align]

static void Main(string[] args)

{

Resume a=new Resume("大鸟");

a.setpersonalinfo("男","29");

a.setworkexperience("1998-2000","xx公司");

//注意:Resume b=a;这其实是在传引用,而不是传值,这样做如同在b纸张上写着简历在a处一样,没有实际的内容的

Resume b=(Resume)a.clone();

b.SetWorkExperience("1998-2000","yy公司");

Resume c=(Resume)a.Clone();

c.SetPersonalInfo("男","24");

a.display();

b.display();

c.display();

}

结果显示:

大鸟 男 29

工作经历 1998-2000 xx公司

大鸟 男 29

工作经历 1998-2000 yy公司

大鸟 男 24

工作经历 1998-2000 xx公司

MemberwiseClone()方法是这样,如果字段是值类型的,则对该字段执行逐位复制,如果字段是引用类型,则复制引用的对象;因此,原始对象及其复本引用同一对象在现实设计当中,一般会再有一个"工作经历"类,当中有"时间区别"和"公司名称"等属性,"简历"类直接调用这个对象即可。

[align=center]浅复制 [/align]



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.MeberwiseClone();

}

}

客户端代码:

static void Main(string[] args)

{

Resume a=new Resume("大鸟");

a.SetpersonalInfo("男","29");

a.workExperience("1998-2000","xx公司");

//b和c都克隆于a,但当它们都设置了"工作经历"时,我们希望的结果是三个的显示不一样

Resume b=(Resume)a.Clone();

b.workExperience("1998-2006","yy公司");

Resume c=(Resume)a.Clone();

c.workExperience("1998-2003","zz公司");

a.Display();

b.Display();

b.Display();

}

显示结果:

//可惜,没有达到我们的要求,三次显示的结果都是最后一次设置的值

大鸟 男 29

工作经历 1998-2000 zz公司

大鸟 男 29

工作经历 1998-2000 zz公司

大鸟 男 29

工作经历 1998-2000 zz公司

[align=center]简历的深复制: [/align]



class WorkExperience :ICloneable//让"工作经历"实现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.MemberwisseClone();

}

}

calss 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 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.workExperience("1998-2000","xx公司");

Resume b=(Resume)a.Clone();

b.workExperience("1998-2006","yy公司");

Resume c=(Resume)a.Clone();

c.workExperience("1998-2003","zz公司");

a.Display();

b.Display();

b.Display();

}

显示结果:

//达到了我们希望的三次显示的结果不同的要求

大鸟 男 29

工作经历 1998-2000 xx公司

大鸟 男 29

工作经历 1998-2006 yy公司

大鸟 男 29

工作经历 1998-2003 zz公司
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: