有个需求,系统要接收外部不同渠道的流量,每个渠道的数据格式有所不同,需要将它们进行特定的处理以符合系统所定义的数据要求,实现这个需求考虑使用适配器模式
我们可以为每个数据源编写一个适配器类,数据转换成期望的格式再送入系统
这个有点像适配器模式,但感觉又不是适配器模式
Target:客户期望获得的功能接口(本地系统期待的数据类型)
Cilent:客户,期望访问Target接口(就是基于本地系统期待的数据类型进行操作)
Adaptee:现有接口,这个接口需要被适配(第三方数据)
Adapter:适配器类,适配现有接口使其符合客户需求接口(把第三方数据转换为本地系统期待的数据类型)
也就是说,当前系统只具备adaptee的功能,但是我期望的是target中的功能;所以我们使用adapter来继承当前adaptee的功能并且实现target的功能。
上面说到的适配器模式都是对于功能的应用,而我们的需求是:将外部数据处理成符合我们系统的数据格式;但本质上的思想是差不多的
所以适配器类就是继承Adaptee实现target接口,但是我们的需求比较特殊,是对数据进行转换,而不是方法转换;即定义一个父类适配器,有个抽象的数据转换方法,子类适配器实现该方法,将自身格式的数据转换为targetData
实现思路
定义一个适配器抽象类,用于转换数据
public abstract class Adapter<T extends BaseData> { // 这里其实不需要extends BaseData,这样的实现方式是为了要T限制在数据处理,而不是随便一个入参都行
public abstract TargetData transform(T t);
}
方法入参是不同格式的外部数据,返回值是我们的目标数据;为了实现这个需求,我们使用了泛型类,T为BaseData的子类;这样定义也是很合理的,因为外部数据有所不同,但是他们还是有一些必须的共同参数;
然后每次接入新的数据源,我们就定义一个适配器,继承Adapter实现相应的transform方法就可以了
@Component
public class DouyinAdapter extends Adapter<DouyinData> { // 这里泛型指定为对应的数据类型
@Override
public TargetData transform(DouyinData douyinData) {
// 相关数据转换操作
return targetData;
}
}
然后就可以啦,我们来看看调用
@RestController
public class DataController {
@Autowired
private DataService dataService;
@Autowired
private DouyinAdapter douyinAdapter;
@PostMapping(value = "/douyin")
public int handleData(@RequestBody DouyinData data) {
TargetData targetData = douyinAdapter.transform(data); // 注意,从这个角度看很像是策略模式,但是策略模式的入参是一致的,而我这里要对不同类型的数据进行处理,不可能直接用父类BaseData,所以严格来看,我使用的是适配器模式和策略模式思想的组合
dataService.handleMyData(targetData);
return 1;
}
}
是不是很简单