背景
接手一个老项目的统计接口,统计最近21周
的数据,返回的结果是一组数组:
[
{"A字段": "A1值", "B字段": "B1值", "week1": 1, "week2": 1, "week3": 2, ......, "week21": 3 },
{"A字段": "A2值", "B字段": "B2值", "week1": 5, "week2": 3, "week3": 12, ......, "week21": 7 },
......
]
封装的结果对象是:
public class StatRetClass {
private String A字段;
private String B字段;
private Integer week1;
private Integer week2;
......
private Integer week21;
}
后来业务改为统计最近27周
的数据,于是类又改为:
public class StatRetClass {
private String A字段;
private String B字段;
private Integer week1;
private Integer week2;
......
private Integer week21;
private Integer week22;
private Integer week23;
private Integer week24;
private Integer week25;
private Integer week26;
private Integer week27;
}
之后又多次修改,最近一次改为79周
,每次修改,都要写上大量的weekX
字段,以及对应的get&set
方法(也可以用lombok
)。
那么是否有方法可以在尽量少修改代码的情况下,支持对统计周数
的调整。
方案
weekX
字段不硬编码,而是在创建对象时,动态添加。
这里使用了cglib
来动态生成属性。
首先将统计的周数量提取为配置变量WEEKCOUNT
,方便通过配置系统
动态修改值。
public static <T extends StatRetClass> T buildCompareModelDto(Class<T> clazz) {
Map<String, Class> propertyMap = Maps.newHashMap();
IntStream.range(0, WEEKCOUNT).forEach(i -> {
propertyMap.put("week" + (i + 1), Integer.class);
});
BeanGenerator generator = new BeanGenerator();
generator.setSuperclass(clazz);
BeanGenerator.addProperties(generator, propertyMap);
return (T) generator.create();
}
原先的new StatRetClassSub1()
和new StatRetClassSub2()
分别改为StatRetClass.buildCompareModelDto(StatRetClassSub1.class)
和StatRetClass.buildCompareModelDto(StatRetClassSub2.class)
。
另:cglib
生成的属性名固定带有$cglib_prop_
前缀,但是get&set
方法没有带前缀。例如生成的week1
属性名是$cglib_prop_week1
,但是get
方法是getWeek1()
。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。