面向接口编程之数据处理模块类图
今天整理了一下数据处理模块的接口和类的关系图
系统架构是基于接口来开发的,通过接口调用各模块的实现,通过容器(Unity)配置具体实现类及相应的参数
所有功能都高度独立和服用,空出来的精力可以把每个功能模块做大做强(每个接口可以又n种实现,按需配置),本篇先讲最基本的数据处理模块的架构
一、数据处理通用接口
数据处理主要是5种接口,添加(IDataAdd)、修改(IDataUpdate)、删除(IDataDel)、查看(IDataView)、获取列表(IDataList)及数据操作总接口(IDataOperate)
以上5种接口定义基本能满足大部分数据操作的需求
测试项目接口配置示例截图:
二、数据库处理子模块相关实现
1、数据库处理子模块主要是TableOperate类(实现接口IDataOperate)
2、对数据库操作必须指定数据库和具体的表,分别通过DbConfig(IDbConfig)和TableSource(ITableSource)来配置,通过接口来获取配置信息,如果有特殊的拆库和拆表逻辑可以通过重新实现IDbConfig和ITableSource来实现
数据操作接口和实现都保持独立,不需要修改
3、TableOperate本身没有数据操作逻辑,是通过泛型仓储类Repository<T>来操作数据库的,仓储类中保留对数据表和字段等信息的映射
其中泛型仓储类Repository<T>中T就是数据领域的模型,该模型上有对数据库中字段的映射关系
4、其实Repository<T>中也是通过对接ORM工具,该ORM工具我在很早就发文介绍过用法
注1:本来是有IRepository<T>接口的,作为TableOperate的属性,IDbConfig和ITableSource是配置在IRepository<T>中的,后来删除了,把Repository<T>封装在TableOperate内部调用
注2:接口是要需要在配置文件中配置调用实例的
注3:这样一来如果系统要更换第三方ORM工具就不能通过配置IRepository来实现了,还得实现ITableOperate接口和新的Repository<T>来实现
注4:为什么没有IRepository<T>,是因为我为以后调用级权限控制留下空间,如果需要配置IRepository<T>,也就意味着拿个这个接口就可以对整个表做任何操作,这不是我想看到的结果
当然拿到IDataOperate接口也是可以对整个表做任何操作,但是还有其他接口(IDataAdd,IDataView)可用,只要在每个使用的地方配置最小权限接口,并封装一个该接口的实现即可防止权限提升
测试项目配置示例截图:
三、文本文件处理相关实现
1、文本操作同理也是有一个数据源配置接口IFileSource(及类FileSource)
2、文件操作实现暂时较为简单,主要用于对配置文件操作及期缓存来用的
注:由于文件操作和数据操作同样实现的数据操作基本接口,配置信息存储可以在数据库和文件中都很方便
五、数据处理适配类(DataOperate)
由于该架构是面向接口低耦合的,不同模块间调用数据操作,但是引用另一个模块的模型类显然不能合适,那样就成相互依赖了,这个时候这个类就出来调解这个尖锐矛盾了
1、DataOperate中属性Operater是真是的数据处理对象
2、T类型是接入模块的模型类,S是被调用的模块的模型类,Converter(IConvertType)是中间的桥梁,负责两种模型的相互转化
3、IConvertType同样是一个接口,可以自定类型转化逻辑配置上,当然ConvertType类基本能满足大部分转化需求,因为ConvertType中有一个Map属性,可以做好两个类型中不同属性名的映射
六、数据保存实现
1、其实没有数据保存这块涉及也是很处理这类需求,由于数据保存是系统间对接用到最频繁的功能有必要单独拿出来强化一下
2、典型的用法是日志记录和数据同步,这些只要求一个单向的操作不需要相互交互
3、数据处理接口都有建模约束(where T : class, new()),而实际场景我们可能只是一个字符串、数据、Table等,这个时候建一个模型是可能有些浪费或者不方便,这个时候通过配置Converter来转化为需要的格式
4、文件处理大部分并不需要模型,只要一个格式
这样数据处理模块也算告一段落,有什么调整的我会更新该文
有时间再补上“转化和格式化"模块(及Razor子模块)、日志模块、配置模块、缓存模块等接口及类图,有时间我可能还会发示例项目代码(实际项目代码是不能发的,见谅)上来
最好强调一下面向接口编程的重要性,各个模块都是可能相互调用的,但是我们不能相互引用,或者重复开发
比如日志模块可能调用数据库模块存储日志页可以调用文件,或者http或socket等,日志模块没有必要引用所有可以存储的方式,也没必要再作一个文件日志子模块,数据日志子模块,等等,日志只要调用一个存储接口(ISave),以后不需要修改日志模块
另外日志可能使用数据库存储,数据库操作也可能要记录日志,两个模块会出现循环引用的情况,通过接口抽象可以避免模块相互引用及以后扩展的问题