背景

接手一个老项目的统计接口,统计最近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()


noname
317 声望51 粉丝

一只菜狗