很多时候,Web Service程序以应用在SOA系统中的无连接状态形式存在,即,服务端对客户端请求的数据都是即时返回,不会为客户端保留即时数据,而由于跨平台的特性,不同语言间可以无缝兼容的只有基本数据类型,因此,对于其它一些复杂数据,我的系统采用了XML格式的定义方式。
对于返回的数据无外乎以下三种模式:
1、 基本类型
2、 键-值(-类型)列表类型
3、 二维表类型
对于后两种类型,我使用了TReturnManager和TXmlReturn类来进行处理,具体说明请见:
http://blog.csdn.net/zhmnsw/archive/2006/10/27/1353418.aspx(Web Service接口数据交换标准--返回值)。
之前,TReturnManager处理了TStrList(自定义的键-值-类型列表类型)、DataTable类型和Exception、TSvrException(自定义异常,附加异常编码和信息以及DataTable类型额外数据),对于这些类型的封装都是在类内部进行。
但随着开发使用的数据类型逐渐增多,TReturnManager类越来越臃肿,尤其是使用到NHibernate(以下简称NH)时,由于NH只能返回IList类型,因此TReturnManager类又需要增加与之相应的处理函数,导致该类扩充越来越困难,加之每次都需要修改TReturnManager单元,给代码维护带来不必要的麻烦。
为了解决这个问题,我们可以使用一个适配器模式,定义以下接口:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
IDataListAdapter接口只有4个属性,分别返回二维表、行、列以及数据标识名称,之后为每一种数据类型定义一种继承自该接口的适配器,这样在处理的时候,只处理IDataListAdapter接口即可。于是TReturnManager类的处理函数只剩下两个:处理IDataListAdapter接口的和处理的IException接口(该适配接口实现同前一个,在此不赘述)。
以下为相应的类图(该图没有显示IException接口相关类型):
![](https://p-blog.csdn.net/images/p_blog_csdn_net/zhmnsw/f89467fb4df14d3e87a3c2d9797f07bd.gif)
该类图中有三个适配器,分别是:
组合了DataTable的TDlaDataTable。
组合了TStrList的TDlaStrList(TStrList可以转换成单行记录的DataTable)
组合了IList的TDlaEntityList(目前为NH返回值,该适配器使用了反射机制将数据转换成DataTable型,但仍需扩展。NH数据与DataTable间的转换效率将在其它地方阐述)。
由于IDataListAdapter接口的存在,每次数据类型解析的更动,都只需增加或修改相应类型的适配器即可,无需更动TReturnManager单元。