考虑到上述问题,我们在数据实体的表现上采用了另外一种方式,那就是利用DataSet。DataSet是微软在ADO.Net中新提出的数据对象,同ADO的Recordset不同的是,他能够容纳多个记录集。DataSet类似于一个内存数据库,由多个DataTable组成,而一个DataTable又有多个Column。这样的结构,使得他可以同数据库很好的进行映射。同时,我们吸取了J2EE架构中CMP使用XML文件定义实体类结构的优点,采用了类似的解决方案。
因此,在这个方面我们是这样来进行处理的:
1) 核心类库定义了EntityData类,这个类继承了DataSet,添加了一些方法,用来作为所有实体类的框架类,定义了各个实体类的一般结构,至于每个实体类具体的结构,在运行时刻由下述办法确定:
2) 实体类的定义通过XML文件来确定,该XML文件符合JIXML对象实体描述语言的规范(注:JIXML是我们开发的 对象-实体 映射语言),用于确定实体类的结构。例如,一个关于订单的实体类的定义可能类似于下面的结构:
3) 实体对象的结构由一系列的类构造器在运行时刻,根据上述规范制定的XML来生成。这些类构造器实现IClassBuilder接口。我们在系统核心类库中预定义了一些标准的Builder,一般情况下,直接使用这些标准的Builder就可以了。
类构造器采用的类构造工厂的设计模式,如果使用者觉得标准的Builder不能满足要求,也可以扩展IClassBuilder接口,编写自己的类构造器,然后在系统配置文件中指明某各类的类构造器的名称即可。
IClassBuilder的定义如下:
这个部分的结构可以用类图表示如下:
当使用者需要某个实体类的时候,只要采用如下语句:
EntityDataManager的GetEmptyEntity方法通过调用ClassBuilder的BuildClass来实现,并且实现对象的缓存功能。
ClassBuilder的BuildClass方法实现如下:
这儿综合使用了Builder和Factory的设计模式。ClassBuilderFactory的作用是根据实体类的名称,读取配置文件中相应的类构造器的具体类名,并返回具体的类构造器。
配置文件ClassBuilders.xml的结构很简单:
如果没有为某个实体类指明具体的Builder,系统将调用默认的Builder来构造实体对象的结构。
系统同时提供了实体对象缓存服务。通过上述方式产生的实体对象可以被缓存,这样,在第二次调用该对象时,可以从缓存中读取,而不用从头重新生成,从而大大提高了系统的性能。
在实际的开发过程中,我们感觉到,数据实体层采用这种设计模式具有以下优点:
· 实体类定义XML文件可以通过工具来自动生成,减轻开发工作量。
· 在执行查询操作时,不论是返回一个实体,还是多个实体,数据的表现方式都一样,都是EntityData,而不存在如上面所述的单个对象和数据集的表现方式不统一的问题。
· 在修改实体类的定义时,如果修改的部分不涉及到业务逻辑的处理,只需要修改XML文件就可以了,不用修改其它程序和重新编译。
· 系统提供的实体对象缓存服务可以大大提高了系统的性能。
· 类构造工厂的设计模式大大提高了系统的灵活性。
因此,在这个方面我们是这样来进行处理的:
1) 核心类库定义了EntityData类,这个类继承了DataSet,添加了一些方法,用来作为所有实体类的框架类,定义了各个实体类的一般结构,至于每个实体类具体的结构,在运行时刻由下述办法确定:
2) 实体类的定义通过XML文件来确定,该XML文件符合JIXML对象实体描述语言的规范(注:JIXML是我们开发的 对象-实体 映射语言),用于确定实体类的结构。例如,一个关于订单的实体类的定义可能类似于下面的结构:
3) 实体对象的结构由一系列的类构造器在运行时刻,根据上述规范制定的XML来生成。这些类构造器实现IClassBuilder接口。我们在系统核心类库中预定义了一些标准的Builder,一般情况下,直接使用这些标准的Builder就可以了。
类构造器采用的类构造工厂的设计模式,如果使用者觉得标准的Builder不能满足要求,也可以扩展IClassBuilder接口,编写自己的类构造器,然后在系统配置文件中指明某各类的类构造器的名称即可。
IClassBuilder的定义如下:
public interface IClassBuilder { EntityData BuildClass(string strClassName); //获取类数据结构 SqlStruct GetSqlStruct(string strClassName,string strSqlName); } |
这个部分的结构可以用类图表示如下:
当使用者需要某个实体类的时候,只要采用如下语句:
EntityData entity=EntityDataManager.GetEmptyEntity("Product"); |
EntityDataManager的GetEmptyEntity方法通过调用ClassBuilder的BuildClass来实现,并且实现对象的缓存功能。
ClassBuilder的BuildClass方法实现如下:
public EntityData BuildClass(string strClassName) { IClassBuilder builder=ClassBuilderFactory.GetClassBuilder(strClassName); return builder.BuildClass(strClassName); } |
这儿综合使用了Builder和Factory的设计模式。ClassBuilderFactory的作用是根据实体类的名称,读取配置文件中相应的类构造器的具体类名,并返回具体的类构造器。
配置文件ClassBuilders.xml的结构很简单:
|
如果没有为某个实体类指明具体的Builder,系统将调用默认的Builder来构造实体对象的结构。
系统同时提供了实体对象缓存服务。通过上述方式产生的实体对象可以被缓存,这样,在第二次调用该对象时,可以从缓存中读取,而不用从头重新生成,从而大大提高了系统的性能。
在实际的开发过程中,我们感觉到,数据实体层采用这种设计模式具有以下优点:
· 实体类定义XML文件可以通过工具来自动生成,减轻开发工作量。
· 在执行查询操作时,不论是返回一个实体,还是多个实体,数据的表现方式都一样,都是EntityData,而不存在如上面所述的单个对象和数据集的表现方式不统一的问题。
· 在修改实体类的定义时,如果修改的部分不涉及到业务逻辑的处理,只需要修改XML文件就可以了,不用修改其它程序和重新编译。
· 系统提供的实体对象缓存服务可以大大提高了系统的性能。
· 类构造工厂的设计模式大大提高了系统的灵活性。