一只蝴蝶

人生就是一场拼争/每天都在攀登/爬上这座山/越过那道岭/眼前又是一座峰

  :: :: :: :: :: 管理 ::

在接触到一个系统中(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);
            }

        }


总之,费了很大的牛劲,实现了通用集合类。但是是按照原来的思想,设计成一个具体数据类对应一个具体集合类呢,还是设计成不同的具体数据类,对应相同的一个通用集合类呢?是否有什么设计标准呢?就不知道了!


 

posted on 2006-01-04 16:13  一只蝴蝶  阅读(775)  评论(0)    收藏  举报