背景
接手一個老專案的統計介面,統計最近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()
。