服务数据映射模式

设计原因

由于服务越来越小型化或者分工越来越精细,这样的场景越来越多见:

需要从多个不同的服务(SOA服务、Restful服务)获取数据,截取其中一部分返回进行进一步处理,生成自身领域模型需要的业务数据

乍看其实很简单,就是获取数据——MAP映射数据——对映射数据执行领域业务逻辑

但实际情况可能复杂的多

获取数据

  • 获取数据的时候,数据源不一致,对每种数据源要进行封装
  • 数据源获取的时候,每一项业务可能获取的数据源不一致
  • 获取的数据源可能互相依赖,比如B数据源的Request需要A数据源的Response
  • 获取数据源无互相依赖,为了性能,可能需要并发获取,或者对每种数据源进行设置超时(可能某些数据源自带超时或熔断功能,有些没有,又需要自己实现)

单看以上每种问题都比较好解决,但是这些问题混合在一起的时候就很头大了

MAP映射数据

  • 对同一种数据源,MAP的粗细程度可能不一样,有些需要精细Map,有些只需要简易的Map
  • Map代码可能散落在代码库各处,不方便之后维护的人阅读,后来的人改起来吃力,可能就自己重写了,导致有多种重复Map

所以萌发了写一套代码能通吃处理以上问题

目的是能:

  • 最大限度重用数据源调用
  • 最大限度重用数据映射逻辑
  • 灵活的数据获取和映射
  • 新创建数据源、数据映射可以方便集成进现有架构
  • 业务变化,某些映射逻辑过时后,可以只需在一处修改(映射代码只会出现一次)

原理模型

RequestEntity封装请求类,容纳所有DataSource请求所需要的字段(可以是巨型实体)

ResponseEntity封装返回类,容纳所有Mapper映射后的返回字段(可以是巨型实体)

使用方法

  1. 首先实例化DataSource的子类,一个子类代表一种数据来源
  2. 创建Mapper对象,由于有TResponse协变泛型进行约束,保证数据源只有能处理的Mapper进行处理
  3. 将Mapper加入数据源MapperList
  4. FetchData从第三方数据源获取数据
  5. GetResponse遍历所有Mapper进行第三方数据到ResponseEntity的映射
  6. 如果需要从别的数据源获取,可以直接重复1-5的操作,ResponseEntity作为已经处理过的数据,可以参与到后续的映射中
  7. 如果需要并发获取,可以单独写方法创建多个线程同时执行多数据源的Fetch操作

代码实现

参考火车票动态答案项目、zhixingflight动态答案项目

改进方向

MapperList也可以影响DataSource的RequestEntity

由于大量使用组合的方式,去除耦合,导致有可能需要将Mapper切分的很细,具体还是需要使用的人来决定是否切分Mapper

原文地址:https://www.cnblogs.com/enigmaxp/p/8482025.html