在接触到一个系统中(Delphi实现)自定义了很多数据类,以及操纵数据的集合类(List)。
各个集合类有相同的属性(例Item、Count),相同的方法(例Add、Remove、Copy),只是方法所处理的数据是某一种特定的数据类,另外在某种方法里要调用所处理的数据类的方法(例SaveToStream)。
看上面AccompanyDataList处理的是AccompanyData,FormDataList处理的是FormData。但他们的方法是如此的相似。
总之有一种数据类,就有一种集合类。
在把此系统向.NET环境移植时,把各种数据类用C#改写了。但在改写集合类时,考虑到要重复很多相似的代码,而各集合类的属性名称、方法名称相同,要实现的功能相同,即把数据类的某个实例加入到集合类中,或者从集合类中删除某个实例,所以想象设计一个通用的集合类,根据集合类实例化时,类的使用者传递的参数类型,来决定这个集合类是哪种数据的集合。
这次改变,就是要实现通用的集合类,目的是为了减轻工作量,避免重复很多相似的代码。但不知此设计是否合理?为什么原系统没有合并集合类呢?
不管这些了。下面着力实现通用集合类。关键是获取集合类实例化时传递的参数的类型,再根据这个类型,创建此类型的实例,加入到集合中,为了接收任何类型,使用一个object型的变量,在需要返回某种数据类型时也只能用object代替。这样集合类的使用者必须使用强制类型转换。
public class DataList
{
private object DataType;
protected ArrayList List;
public DataList(object dataType)
{
DataType=Activator.CreateInstance(dataType.GetType());
List=new ArrayList();
}
public virtual int Add()
{
return List.Add(Activator.CreateInstance((DataType.GetType())));
}
public virtual int Add(object dataType)
{
if (dataType.GetType()==DataType.GetType())
{
return List.Add(dataType);
}
else
{
return -1;
}
}
public virtual object AddItem()
{
int index=Add();
return List[index];
}
}集合类的使用:
DataList aFormList=new DataList(new FormData());
FormData aForm=(FormData)aFormList.AddItem();
DataList aFieldList=new DataList(new FieldData());
FieldData aField=(FieldData)aFieldList.AddItem();基本上是实现了要求。
主要一点不同就是原来类的设计者要在集合类的内部实现类型转换,而现在是类的使用者要在集合类的外部实现类型转换。
在具体集合类调用所处理的具体数据类的方法时,可能是这样子:
public virtual void SaveToStream(Stream stream,bool isShallow)
{
for(int i=0;i<Count-1;i++)
{
((RecordData)List[i]).SaveToStream(stream,isShallow);
}
}也是在集合类内部实现了类型转换(RecordData)。但在通用集合类怎么办呢?想了一下,使用运行时多态。即把通用集合类要调用的具体数据类的方法,用抽象基类包装,各个具体数据类继承自这个基类。然后在集合类中调用基类相应方法,这样根据运行时多态,达到调用具体类(子类)的方法的目的。
基类:
public abstract class DataBase
{
public abstract void Assign(object item,bool isShallow);
public abstract void SaveToStream(Stream stream,bool isShallow);
public abstract void SaveToFile(string fileName,bool isShallow);
public abstract void LoadFromStream(Stream stream,bool isShallow);
public abstract void LoadFromFile(string fileName,bool isShallow);
}子类:
public class RecordData:DataBase
{
public override void SaveToStream(Stream stream,bool isShallow)
{
//
}
public override void SaveToFile(string fileName,bool isShallow)
{
//
}
public override void LoadFromStream(Stream stream,bool isShallow)
{
//
}
public override void LoadFromFile(string fileName,bool isShallow)
{
//
}

public override void Assign(object item,bool isShallow)
{
if ((item as RecordData)!=null)
{
formID =((RecordData)item).FormID;
}
}
}为了实现通用,涉及到具体类的方法的参数,依然用object代替。而在方法的内部,要用类型转换。
通用集合类中对应方法的实现,即用基类转换类型:
public virtual void SaveToStream(Stream stream,bool isShallow)
{
for(int i=0;i<Count;i++)
{
((DataBase)List[i]).SaveToStream(stream,isShallow);
}
}
总之,费了很大的牛劲,实现了通用集合类。但是是按照原来的思想,设计成一个具体数据类对应一个具体集合类呢,还是设计成不同的具体数据类,对应相同的一个通用集合类呢?是否有什么设计标准呢?就不知道了!


浙公网安备 33010602011771号