字典转换配置化重构实践总结
本文介绍笔者在字典转换配置化过程中的实践总结,在此总结记录,加深认识。
问题背景描述
在现有工程中,有关转换的函数散落分布在各个模块,既有界面展示的转换,又有与后台交互的字段转换,还有自定义转换等众多使用场景。这些转换关系依赖的数据源,有些是配置在本地文件中,有些固化在代码中,还有是动态请求得到的。维护这么多数据源分散的转换关系很麻烦,容易出错。经过分析,这些转换关系本质逻辑都是一样的,无非是数据源以及使用接口不同而已。
基于上述问题,提出将转换关系数据配置化的方案,以提高灵活性。下面从数据模型、接口以及核心实现三个方面来介绍。
数据模型
分析现有实现的数据模型,梳理出两类数据源:
- 与后台数据相关,具体有以下三种情况:
- 接口文档中明确指定的接口字典以及字典标识。
- 只在接口文档备注项中零散的定义,没有标准的字典标识。
- 虽然后台有字典定义,但不适合前端直接使用的字典数据,例如:性别,假设后台接口定义
1
为男,0
为女,前端需要展示为先生、女士
,这类转换,需纳入自定义转换类别。
- 自定义转换
- 转换字典
key
依赖于柜台定义,但value
取决于使用场景,由使用者具体决定,上面提到的性别就是一个典型的例子。 - 与柜台定义无关,完全由使用者定义的转换关系。比如,买卖的自定义价格档位买一价,买二价等,在使用时,根据具体行情获得价格。
- 转换字典
通过上述分析,可进行如下建模,新建两个文件BackEnd.xml
和Custom.xml
,分别表示后台数据字典和自定义字典,设计如下的数据结构:
<?xml version="1.0" encoding="GB2312" ?>
<ROOT>
<Dict_Market>
<Item0 key="1" value="深圳">
<Item1 key="2" value="上海">
</Dict_Market>
// ... 更多后台字典定义
</ROOT>
自定义字典文件可设计如下:
<?xml version="1.0" encoding="GB2312" ?>
<ROOT>
<Dict_Sex>
<Item0 key="1" value="先生"> // 后台字典中为男、女
<Item1 key="2" value="女士">
</Dict_Sex>
// ... 更多自定义字典
</ROOT>
接口
分析现有工程中的使用场景,字典模块对外提供三个功能接口以及一对初始化接口:
- 初始化以及反初始化接口
- 根据指定字典
Id
,获得对应字典数据集合 - 根据指定字典
Id
以及字典key
,获得对应的value
值 - 根据指定字典
Id
以及字典value
,获得对应的key
值
核心实现
通过单例形式对外提供服务,提供以上五个接口即可,详细设计类图如下:
非功能化需求
-
性能
-
为了提高效率,在实现时,采用两个
map
存储字典数据,一个map
中的value
为vector
类型,目的是获取与配置文件中相同顺序的字典值;另一个map
中的value
采用map
结构,提高搜索效率。 -
对外接口采用
inline
方式,返回指针,减少数据拷贝,提高效率。
-
-
异常处理
- 为更快的发现配置错误或者使用错误,需要考虑如下异常情况,并提示使用者:
- 字典配置文件不存在或者格式错误
- 字段
Id
内无有效数据,包括字典项为空和数据项(value
或者key
)缺失 - 根据实际场景,在字典项中增加
key
值为空的项,对应的value
根据实际场景来设置。 - 同一个字典Id中,存在重复
key
时 - 不同字典配置文件中,存在重复字段
Id
时
- 为更快的发现配置错误或者使用错误,需要考虑如下异常情况,并提示使用者:
-
未来扩展需求
- 可根据实际需要,提供
key
值为整形等接口函数,方便使用 - 多数据源聚合显示
- 可根据实际需要,提供
-
安全
- 可考虑将配置文件以加密形式存储,使用时在内存中解密。
-
升级
- 需要一套升级框架来保证配置文件的升级正确性
小结
本文简要描述了转换字典配置化重构过程中的步骤以及针对非功能型需求的思考,做好这一步,为后面构建配置中心打好基础。