您的位置:首页 > 其它

浅谈反射与特性在接口系统中的应用(编码表转化)

2007-12-20 14:09 309 查看
问题描述:

业务系统A和B需要共享数据,以达到数据利用最大化,减少工作人员的录入数据的工作量。说明一下,业务系统A和B各自使用不同的编码表,简单的说,在业务系统A中,性别是使用01和02代表男和女,而在业务系统B中,性别则采用了m和w表示男和女。现在,这两个系统要共享性别这个数据项,所以我们需要做的必不可少的工作就是:编码表的转化。这个问题有很高的普遍性,基本上只要是业务系统之间共享数据,那么这一步是必不可少的。今天,我就对此问题谈一谈我的解决之道,供大家探讨。

解决思路:

1) 我们最容易想到的办法就是,编写一个方法,针对输入的编码进行匹配转化,如一下代码所示:

public static string SexCodeToJS(string code)

然后,在外部进行调用此方法即可。如果我们的编码表转化数量比较少的话,这一种方法,显然已经可以满足要求了。但假如我们有很多的编码表需要转化,这一种方法使用起来应该是很吃力的。而且,一旦数据项的编码之间对应关系一旦发生变化,我们就必须要改写程序,然后编译、发布。显然此方法的灵活性还不太好。那么我们就需要寻找另一种灵活的,可以应对编码对应关系可能会变的方法。

1) 使用数据库或者xml存储编码表之间的对应关系。使用数据库也好,xml也好,都是把问题的可变性单独分离出来,以数据库存储为例,可以设计如下表结构(脚本如下):

create table CodeConvert

(

id int identity(1,1) primary key,

codeType varchar(10), --编码的类型

codeA varchar(10), --业务系统A的编码

codeA_Name varchar(20), --业务系统A的对应编码的描述

codeB varchar(10),--业务系统B的编码

codeB_Name varchar(20) --业务系统B的对应编码的描述

)

在这个表里存储编码之间的映射关系。现在,如果你需要转化,那么你就需要查询这个表,就可以得到转化后的编码。而且一旦编码之间的对应关系变了,那么你只需要修改这个表里的数据即可完成修改,相对上一种方法,已经增加抗变性。再回头看,抗变性是增加了,可是客户程序使用的时候仍然比较麻烦,仍然需要关心,哪个编码需要转化。其实,从职责分配的角度讲,哪个编码需要转化,是在使用之前就可以确定下来的事情,所以我们可不可以让编码自动转化呢?如果可以的话,那么客户程序就不再需要关心哪个编码需要转化的事情啦,毕竟这是一件烦人的事情。现在,我们整理一下思路,假设有一个负责转化的方法,如下:

public static string ConvertCode(string codeType,string systemACode)

{}

那么,目前如果有一个实体类Person需要转化编码的时候,需要调用:

Person p = GetPerson();

p.SexCode = ConvertCode("CodeType",p.SexCode);

p.MarriageStatusCode = ConvertCode("CodeType",p.MarriageStatusCode);

可以看出,我们需要知道哪一个属性的编码需要转化。那么,我们希望编码可以自动转化,使用编码转化时,不再关心哪一个属性的编码需要转化,代码如下:

Person p = GetPerson();

p = ConvertObjectCode(p); //一次性把所有需要转化的编码全部转化。

这样的代码看起来会比较舒服,客户代码只需要关心何时转化编码,而不关心编码如何转化,这就是职责的分离。

我们应该怎样编写ConvertObjectCode(object convert_obj)方法呢?下面就重点介绍使用反射和特性(自定义属性)就可以做到。

为了更好的提高方法的使用性,我们会给ConvertObjectCode方法添加一个参数,用于指示,编码转化的方向,即:是从业务系统A到B还是B到A。添加这个参数这个方法就可以做到双向转化啦。

让我们继续探讨ConvertObjectCode方法的功能吧。在这里,这个方法需要做的事情是:转化类的属性编码,但要转化的结果则归属于类的属性,因为每个属性转化后的结果是不一样的,而要转化为什么,类的属性是知道的。所以,在这里我们需要再次细化职责,ConvertObjectCode方法只负责转化,而转化为什么则由类的属性承担。看到这里,可能你已经知道如何做啦,那就看一下代码吧。

首先,需要编写一个特性,用于标注哪一个类的属性需要转化,做何种转化。代码如下:

[AttributeUsage(AttributeTargets.Property,AllowMultiple = false)]

public class CodeConvertAttribute:Attribute

其次,在需要做编码转化类的属性上加特性。代码如下:

[CodeConvert(CodeType.Sex)]

public string Sex

最后,做转化的动作,如下:

public static object AutoConvertCode(object convertObj,bool ToLocal)

现在,你就可以轻松的对任意的对象进行编码转化了,如果某个类的属性需要增加编码转化的工作,那么只需要把特性CodeConvert添加到对应的属性上即可,剩下的事情就不用操心啦。怎么样,现在的你还觉得特性和反射遥不可及嘛?

注:之所以写这样的一片post主要是前一段时间,发布了几篇关于反射特性原理的文章,很多朋友都说应用起来有点困难,这一篇就算是对这两篇文章的补充吧。 另外,今天也是一个值得庆祝的日子,因为我自己的小站:问题小站已经开通

了。这篇post也算是给它的贺礼吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: