答案:发表日期: 17/04/2002 18:51:10
发表人: Ashish Jaiman
发表人信箱: Ashish.Jaiman@lexign.com
发表人网址: http://www.lexign.com
与其不断地创建类实例,有时反不如使用原型克隆方法,拷贝已有的实例,然后适当地作些改动。当使用的子类仅仅在对象类型上不同于父类,也可以用原型克隆方法来减少子类数量。
===========================================================
创建类的实例是相当花费时间而且比较复杂的事,与其不断地创建类实例,有时反不如使用原型克隆方法,拷贝已有的实例,然后适当地作些改动。当使用的子类仅仅在对象类型上不同于父类,也可以用原型克隆方法来减少子类数量。
原型设计模式的重点在于“用克隆的方式创建对象”。有时为了得到不同的对象类型而创建不同子类,这时用原型设计就只需要创建一个子类(在这个子类里有指向基类的引用),然后创建这个子类的对象。以后就只要创建这个子类的对象就能用了。每个对象都是能被克隆的,使用原型克隆将大大减少子类的数量。
用系统的ICloneable命名可以实现克隆。ICloneable的唯一成员就是Clone方法,它将返回一个新的类实例,并包含与科隆对象同样的参数值。
ICloneable.Clone 方法的描述:
[Visual Basic] Function Clone() As Object
[C#] object Clone();
必需指出的是,Clone()方法是一种“浅”拷贝,它只返回指向原型的引用。另外还有一种“深”拷贝,它拷贝整个实例对象。用ISerializable接口可以实现对象的深拷贝。
克隆对象的任何变化都将影响到原型,反之亦然。克隆方法的另外一个不足之处在于它的子类都必需使用Clone()方法,很难使用其他的拷贝方法。
在示范例子里(文末可以下载),我创建了一个EmpData类,它有ICloneable和ISerializable二种接口。ICloneable用于创建“浅”拷贝,ISerializable用于创建“深”拷贝。前者仅拷贝对象的引用,后者则拷贝整个对象。EmpData类有二个方法:GetEmpData和ChangeEmpData。前者将源对象克隆成为一个字符串,后者则可以对其进行修改。
二种方法都可以被使用,并用于验证深浅克隆方法的不同。浅克隆对象的变化将影响到被克隆的原型对象,而深克隆对象的变化则不改变原型对象数据。
EmpData的构造函数是挺花时间的,因为它要读取XML文件并创建对象。
XML文件:
<employees>
<employee>
<firstname>ashish</firstname>
<lastname>jaiman</lastname>
</employee>
<employee>
<firstname>jaya</firstname>
<lastname>pandey</lastname>
</employee>
<employee>
<firstname>neeraj</firstname>
<lastname>jaiman</lastname>
</employee>
<employee>
<firstname>ashutosh</firstname>
<lastname>sharma</lastname>
</employee>
<employee>
<firstname>zerman</firstname>
<lastname>billingslea</lastname>
</employee>
<employee>
<firstname>bernd</firstname>
<lastname>burkhardt</lastname>
</employee>
<employee>
<firstname>sanjeev</firstname>
<lastname>bhutt</lastname>
</employee>
<employee>
<firstname>li</firstname>
<lastname>li</lastname>
</employee>
</employees>
C#执行程序:
using System;
using System.Xml;
using System.IO;
using System.Collections;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable()]
public class CEmpData: ICloneable,ISerializable {
private ArrayList ArrEmp;
public CEmpData() {
ArrEmp = new ArrayList();
InitializeData();
}
private void InitializeData() {
XmlDocument xmlDoc = new XmlDocument();
CEmp objEmp;
xmlDoc.Load("empdata.xml");
foreach(XmlNode node in xmlDoc.DocumentElement.ChildNodes) {
objEmp = new CEmp();
objEmp.FName = node.SelectSingleNode("firstname").InnerText;
objEmp.LName = node.SelectSingleNode("lastname").InnerText;
ArrEmp.Add (objEmp);
}
}
public CEmpData(SerializationInfo info,StreamingContext context) {
int intCount=0;
CEmp objEmp;
ArrEmp = new ArrayList();
intCount = (int)info.GetValue("emp_count", intCount.GetType());
for (int intIndex = 0;intIndex<intCount;intIndex++) {
objEmp = new CEmp(info,context,intIndex);
ArrEmp.Add(objEmp);
}
}
public void GetObjectData(SerializationInfo info,StreamingContext context) {
CEmp objEmp;
info.AddValue("emp_count", ArrEmp.Count);
for (int intIndex = 0;intIndex<ArrEmp.Count ;intIndex++) {
objEmp = (CEmp)ArrEmp[intIndex];
objEmp.GetObjectData(info,context,intIndex);
}
}
public object Clone() {
return this;
}
public object Clone(bool Deep) { &
上一个:需求的实践(2)
下一个:转贴一篇CCBOY的好文——《专栏声音》转向面向对象的12个步骤