惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
Scott Helme
Scott Helme
爱范儿
爱范儿
WordPress大学
WordPress大学
博客园 - 三生石上(FineUI控件)
阮一峰的网络日志
阮一峰的网络日志
博客园 - Franky
V
V2EX
腾讯CDC
博客园_首页
博客园 - 司徒正美
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Tailwind CSS Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
小众软件
小众软件
J
Java Code Geeks
大猫的无限游戏
大猫的无限游戏
月光博客
月光博客
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog
雷峰网
雷峰网
Stack Overflow Blog
Stack Overflow Blog
IT之家
IT之家
罗磊的独立博客
Recorded Future
Recorded Future
博客园 - 聂微东
O
OpenAI News
S
Secure Thoughts
Hacker News: Ask HN
Hacker News: Ask HN
S
Schneier on Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
Y
Y Combinator Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Project Zero
Project Zero
宝玉的分享
宝玉的分享
K
Kaspersky official blog
N
Netflix TechBlog - Medium
T
The Exploit Database - CXSecurity.com
Google Online Security Blog
Google Online Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Webroot Blog
Webroot Blog
云风的 BLOG
云风的 BLOG
Simon Willison's Weblog
Simon Willison's Weblog
C
Check Point Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
L
LINUX DO - 热门话题
美团技术团队
L
Lohrmann on Cybersecurity

博客园 - today

赚钱和生活 Tnsping 和TCP/IP 中的ping 的區別 办公自动化漫谈培训有感 SQL Server 64 bit linked server Error with Sql server 32 bit 组合条件查询(初版) 合并DataGrid的单元格 小心使用@@identity BuildSql增加了【生成数据库文档】的功能了 SQLServer2000辅助工具版本更新了 打造迅速响应的用户界面 我的SQL Server2000辅助工具 (翻译)从底层了解ASP.NET体系结构 (翻译)在C#中定义和使用自己的特性 搜索指定域名的小工具 (翻译)反射的第二部分:Emit (翻译)反射的第一部分:发现和执行 在SqlServer2000的视图中小心使用*符号 我眼中的程序员 一首打油诗
浅谈反射与特性在接口系统中的应用(编码表转化)
today · 2007-12-20 · via 博客园 - today
 

问题描述:

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

解决思路:

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

public static string SexCodeToJS(string code)
    
{
            
string result = string.Empty;
            
switch(code.Trim())
            
{
                
case "01":
                    result 
= "m";
                    
break;
                
case "02"
                    result 
= "w";
                    
break;
            }

            
return result;
    }

 

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

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

create table CodeConvert
(
id 
int identity(1,1primary 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();

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

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

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

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

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

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

[AttributeUsage(AttributeTargets.Property,AllowMultiple = false)]
    
public class CodeConvertAttribute:Attribute
    
{
        
public CodeConvertAttribute(string codeType)
        
{
            
this.m_codeType = codeType;
        }

        
private string m_codeType;
        
public string CodeType //编码的类型
        {
            
get
            
{
                
return this.m_codeType;
            }

            
set
            
{
                
this.m_codeType = value;
            }

        }

    }


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

[CodeConvert(CodeType.Sex)]
        
public string Sex
        
{
            
get
            
{
                
return m_Sex;
            }

            
set
            
{
                
this.m_Sex = value;
            }

        }


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

/// <summary>
        
/// 自动转化实体类的各个属性的编码(系统A与系统B)
        
/// </summary>
        
/// <param name="convertObj">要转化的对象</param>
        
/// <param name="huNanToLocal">true:A的编码转化为B;false:B的编码转化为A</param>
        
/// <returns></returns>

        public static object AutoConvertCode(object convertObj,bool ToLocal)
        
{
            Type type 
= convertObj.GetType();
            PropertyInfo[] props 
= type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            
foreach(PropertyInfo p in props)
            
{
                
object convertObj_value = p.GetValue(convertObj,null);
                
string js_type = string.Empty;
                
object[] customerAttributes = p.GetCustomAttributes(typeof(CodeConvertAttribute),false);
                
if(customerAttributes.Length > 0)
                
{
                    CodeConvertAttribute attr 
= (CodeConvertAttribute)customerAttributes[0];
                    js_type 
= attr.CodeType;
                    
if(ToLocal)
                        p.SetValue(convertObj,ConvertCode(js_type,convertObj_value.ToString()),
null);
                    
else
                        p.SetValue(convertObj, ConvertCode (js_type,convertObj_value.ToString()),
null);
                }

                
            }
    
            
return convertObj;
        }


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

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