我们具体的原型都继承了接口ICloneable,同时也实现了该接口里面唯一个一个方法Clone。我们可以在客户端这样创建对象ConcretePrototype1 p1 = new ConcretePrototype1(1); ConcretePrototype1 c1 = (ConcretePrototype1)p1.Clone();首先我们创建了对象p1,接下来我们用通过p1的科隆方法得到了对象c1,这就是一种浅拷贝(因为MemberwiseClone是浅拷贝)。
接下来我们将要实现的是深拷贝,这个一个相对浅拷贝比较困难的工作,我们在拷贝对象的时候不但要拷贝他的数值型字段同时还要复制它的引用字段(有的时候这种工作是非常困难的也许是不可能的)。
namespace Prototype_Deep{
using System.Collections;
public class ConcretePrototype : ICloneable
{
private int m_ID;
public int ID
{
get
{
return this.m_ID;
}
}
private ArrayList m_arrayList = new ArrayList();
public ConcretePrototype(int id)
{
this.m_ID = id;
this.m_arrayList.Add("FirstObject");
this.m_arrayList.Add("SecondObject");
// ...
}
public object Clone()
{
ConcretePrototype c = new ConcretePrototype(this.ID);
c.m_arrayList = new ArrayList();
c.m_arrayList.Add("FirstObject");
c.m_arrayList.Add("SecondObject");
return c;
}
public ConcretePrototype DeepClone(){
return (ConcretePrototype)this.Clone();
}
}
}
该代码显示了如何实现深拷贝,深拷贝的原则就是对于那些引用的字段您需要new(new之前想想是不是能用前面学过的某个创建型的模式实现,这是一个好的习惯)一个出来,然后对该字段里面的对象一一拷贝,这样以来很容易出现循环拷贝,所以说深拷贝要比浅拷贝更难一些。客户端可以通过ConcretePrototype p = new ConcretePrototype(1);ConcretePrototype c = p.DeepClone();来实现克隆一个新的对象。代码如下:
ConcretePrototype p = new ConcretePrototype(1);
ConcretePrototype c = p.DeepClone();
this.richTextBox1.AppendText(p.ToString()+":"+p.ID.ToString()+"
");
this.richTextBox1.AppendText(c.ToString()+":"+c.ID.ToString()+"
");
c.m_arrayList[0] = "Changed";
for(int i = 0;i<=1;i++){
this.richTextBox1.AppendText(c.m_arrayList[i].ToString());
}
this.richTextBox1.AppendText("
");
for(int i = 0;i<=1;i++){
this.richTextBox1.AppendText(p.m_arrayList[i].ToString());
}
这样我们将看到结果我们在改变科隆出来的对象的时候原来的对象是不变的。前面的浅拷贝我们有做这种比较,有兴趣的读者可以试一试,在FCL中大部分的科隆都是浅拷贝,我们可以看看实现ICloneable接口的类,几乎全部都是浅拷贝。顺便说一下在工作流中关于处理(Process)对象以及其他的相关对象我们可以使用这种Clone的方法,这个您可以参看CRM的WorkFlow中的类,又很多都实现了该方法。
希望我的文章可以帮助您很好的理解设计模式中的原型,关于该模式中的详细信息您可以参看GOF的书上面说得很清楚。在这次实现中我们利用了FCL的接口,没有自己写接口但是效果是一样的。如果在文章中出现什么不对的地方忘网友指正:wu_jian830@hotmail.com谢谢您的支持,希望我们可以共同进步。[@more@]
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/79548/viewspace-925310/
,如需转载,请注明出处,否则将追究法律责任。