这两天公司有个新的需求,要求从对端的接口中获取数据,当我拿到对端的数据结构的时候发现大问题,对端提供的数据格式和我们想要的不太一样。
对端提供(数据含义为:每天分96时数据):
{
"id": "85c6bd59-e914-4fd4-bccc-50ae53433ebb",
"name": "华耀",
"date":"2022-11-24",
"val0000": 15,
"val0015": 28,
"val0030": 48,
............
}
而我们需要的数据是:
{
"id": "85c6bd59-e914-4fd4-bccc-50ae53433ebb",
"name": "华耀",
"date":"2022-11-24",
"timePoint":"0015",
"actValue":28
}
其实就是一个列传行的故事,但是后来又发现一个问题他们报文中传输了一个字段叫device_id,也就是设备id,由于好多系统之前设计的时候没经过统筹考虑导致各个系统统一类型数据维护的不统一,还得需要一些资源数据库去映射,他们穿给我们的是他们在自己系统的id,但是我们需要转换到我们系统,形成我们系统相对应的数据,所以就有了接下来的故事。根据自己的想法结合策略模式写的代码,有错误还请大家指出。(以下策略只是举例了一种策略实现,具体策略还要根据自己业务来进行修订。)
定义策略配置表
此表不是固定写法,不管表是什么样子,只要能够配置你的策略选择就行了,下表是我针对自己业务设计出来的转换策略的表。
/** 定义转换策略配置 **/
create table trans_strategy_config
(
Id INT primary key auto_increment not null comment '编号',
source_table_name VARCHAR(128) not null comment '源表名 原表表名称',
target_table_name VARCHAR(128) not null comment '目标表名称',
trans_strategy VARCHAR(255) not null comment '转换策略',
state_flag VARCHAR(2) not null comment '状态',
table_schema VARCHAR(128) not null comment '表数据库'
) comment '转换配置表 表与表之前的转换(单表)';
定义实体类
/**
* 策略配置
*/
@Data
public class TransformConfig {
private String id ;
private String sourceTableName;
private String targetTableName;
private String transStrategy;
private String stateFlag;
private String tableSchema;
}
策略代码实现
- 定义策略接口
public interface TransformStrategy {
//此方法为核心实现方法根据自己业务自己来定义方法形参以及返回值信息
void transformData(TransformConfig config);
}
- 定义具体实现策略接口实现类
@Component //注意此处要将实现策略的类交给spring管理
public class XxxxxxStrategy implements TransformStrategy{
@Autowared
xxxxxxxxxxxxx
/**
* 此处写本策略具体实现出来的逻辑
*/
public void transformData(TransformConfig config) {
......
}
}
- 定义上下文类
这里其实要注意下,实现的接口是Spring的接口,重写该接口的方法就能获取程序上下文,可以通过applicationContext拿到Bean信息,这要为以后动态选择数据库中策略提供条件。
/**
* 转换上下文类 策略模式的选择器
*/
@Component
public class TransformContext implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* 放置配置属性并且执行
* @param config
*/
public void setConfigContextAndTransForm(TransformConfig config) {
String transStrategy = config.getTransStrategy();
//此处拿到的就是数据库配置的策略,通过配置的策略名称拿到bean,这就需要在策略实现的类上加上注册bean名称,我这边直接用的默认规则,所以数据库也就配置的类的全称首字母小写,这样能够直接找到对应的策略类。
TransformStrategy transformStrategy = (TransformStrategy) applicationContext.getBean(transStrategy);
transformStrategy.transformData(config);
}
}
客户端调用代码
@Component
public class TransformScheduled {
@Autowired
private TransformContext transformContext;
public void transformIt(){
Map<String, Object> condition = new HashMap<>();
condition.put("sourceTableNameLikePrefix","XXX_");
List<TransformConfig> transformConfigs = transformConfigMapper.queryConfigByCondition(condition);
//策略模式
for (TransformConfig transformConfig : transformConfigs) {
transformContext.setConfigContextAndTransForm(transformConfig);
}
}
}
总结
通过以上代码实现,我们只需要构造好TransformContext上下问之后,通过形参入参放置动态注入策略配置,就实现了基于数据库的动态策略。以后可以通过数据库中动态配置来做到业务不同分支逻辑处理的切换,通过不同的策略选择不同的策略类,好处在于对于大批量有共性特点的业务可以完成不同程度的代码业务处理匹配。此模式不太适合个性化较强的数据以及业务,毕竟每添加一种适配方式就要搞一种策略,对于性能以及代码的维护来说都不是很好,所以要根据业务不同来设计不同思维模式的代码。
以上代码仅供参参考,未经允许禁止转载,有错误或者疑问欢迎在下方评论留言。