说明
这个只是编程过程中积累的朴素经验,在业务开发过程中却是行之有效的,希望分享给博友们参考交流学习之用。
问题背景
业务开发过程中,有些简单的处理逻辑,比如对象属性的初始化,对象的属性值的复制,公用的业务处理逻辑的处理等;
(1)情况1:对象属性的初始化
场景:对象中的属性列表是一个数组中的每个值,采用循环反射的方式,代码不美观不好维护性能低。
(2)情况2:对象的复制
场景:对象中的属性值的复制,一般也是采用循环遍历对象的字段反射方式,同样不好维护且性能不如get、set方法。
(3)情况3:业务逻辑的扩散
场景:一般采用if-else或者switch语句去处理多分枝业务,随着时间的推移,业务的发展,分支越俩越多,造成难维护,业务代码混乱。
(2)情况4:不同程序入口,相同处理逻辑,这个不太好解释,之后用几个例子去说明一下。
涉及技能点:策略模式、函数式接口、Lambda表达式
对象属性的处理
说明:在业务开发过程中有几个对象的属性值是一天96个时刻的分列值,所以数据相关属性有96个,数据源一般是96点List,拿数据也是需要96点List,过多的数据属性使得对该对象的访问异常的痛苦,一般采用的是属性字段反射方法。现在采用一种新的方式去处理;
代码如下
// 对重复的代码采用main方法去生成
public static void main(String[] args) {
for (int i = 1; i < 96; i++) {
System.out.println("public static final DtoSetter<BigDecimal, QuarterData> Q"+i+"_SETTER = (value, target) -> {\n" +
" if (Objects.nonNull(target)) {\n" +
" target.setQ"+i+"(value);\n" +
" }\n" +
" };");
System.out.println();
}
}
public static final DtoSetter<BigDecimal, QuarterData> Q1_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ1(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q2_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ2(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q3_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ3(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q4_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ4(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q5_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ5(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q6_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ6(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q7_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ7(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q8_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ8(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q9_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ9(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q10_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ10(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q11_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ11(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q12_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ12(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q13_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ13(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q14_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ14(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q15_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ15(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q16_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ16(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q17_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ17(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q18_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ18(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q19_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ19(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q20_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ20(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q21_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ21(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q22_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ22(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q23_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ23(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q24_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ24(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q25_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ25(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q26_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ26(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q27_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ27(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q28_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ28(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q29_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ29(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q30_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ30(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q31_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ31(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q32_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ32(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q33_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ33(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q34_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ34(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q35_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ35(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q36_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ36(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q37_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ37(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q38_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ38(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q39_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ39(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q40_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ40(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q41_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ41(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q42_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ42(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q43_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ43(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q44_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ44(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q45_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ45(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q46_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ46(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q47_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ47(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q48_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ48(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q49_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ49(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q50_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ50(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q51_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ51(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q52_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ52(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q53_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ53(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q54_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ54(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q55_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ55(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q56_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ56(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q57_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ57(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q58_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ58(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q59_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ59(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q60_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ60(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q61_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ61(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q62_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ62(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q63_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ63(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q64_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ64(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q65_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ65(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q66_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ66(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q67_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ67(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q68_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ68(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q69_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ69(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q70_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ70(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q71_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ71(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q72_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ72(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q73_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ73(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q74_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ74(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q75_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ75(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q76_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ76(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q77_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ77(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q78_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ78(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q79_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ79(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q80_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ80(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q81_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ81(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q82_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ82(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q83_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ83(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q84_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ84(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q85_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ85(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q86_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ86(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q87_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ87(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q88_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ88(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q89_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ89(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q90_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ90(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q91_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ91(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q92_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ92(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q93_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ93(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q94_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ94(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q95_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ95(value);
}
};
public static final DtoSetter<BigDecimal, QuarterData> Q96_SETTER = (value, target) -> {
if (Objects.nonNull(target)) {
target.setQ96(value);
}
};
public static final Map<String, DtoSetter<BigDecimal, QuarterData>> SETTER_MAP;
public static final Map<String, Function<QuarterData, BigDecimal>> GETTER_MAP;
static {
SETTER_MAP = new HashMap<>(96);
SETTER_MAP.put("q1", Q1_SETTER);
SETTER_MAP.put("q2", Q2_SETTER);
SETTER_MAP.put("q3", Q3_SETTER);
SETTER_MAP.put("q4", Q4_SETTER);
SETTER_MAP.put("q5", Q5_SETTER);
SETTER_MAP.put("q6", Q6_SETTER);
SETTER_MAP.put("q7", Q7_SETTER);
SETTER_MAP.put("q8", Q8_SETTER);
SETTER_MAP.put("q9", Q9_SETTER);
SETTER_MAP.put("q10", Q10_SETTER);
SETTER_MAP.put("q11", Q11_SETTER);
SETTER_MAP.put("q12", Q12_SETTER);
SETTER_MAP.put("q13", Q13_SETTER);
SETTER_MAP.put("q14", Q14_SETTER);
SETTER_MAP.put("q15", Q15_SETTER);
SETTER_MAP.put("q16", Q16_SETTER);
SETTER_MAP.put("q17", Q17_SETTER);
SETTER_MAP.put("q18", Q18_SETTER);
SETTER_MAP.put("q19", Q19_SETTER);
SETTER_MAP.put("q20", Q20_SETTER);
SETTER_MAP.put("q21", Q21_SETTER);
SETTER_MAP.put("q22", Q22_SETTER);
SETTER_MAP.put("q23", Q23_SETTER);
SETTER_MAP.put("q24", Q24_SETTER);
SETTER_MAP.put("q25", Q25_SETTER);
SETTER_MAP.put("q26", Q26_SETTER);
SETTER_MAP.put("q27", Q27_SETTER);
SETTER_MAP.put("q28", Q28_SETTER);
SETTER_MAP.put("q29", Q29_SETTER);
SETTER_MAP.put("q30", Q30_SETTER);
SETTER_MAP.put("q31", Q31_SETTER);
SETTER_MAP.put("q32", Q32_SETTER);
SETTER_MAP.put("q33", Q33_SETTER);
SETTER_MAP.put("q34", Q34_SETTER);
SETTER_MAP.put("q35", Q35_SETTER);
SETTER_MAP.put("q36", Q36_SETTER);
SETTER_MAP.put("q37", Q37_SETTER);
SETTER_MAP.put("q38", Q38_SETTER);
SETTER_MAP.put("q39", Q39_SETTER);
SETTER_MAP.put("q40", Q40_SETTER);
SETTER_MAP.put("q41", Q41_SETTER);
SETTER_MAP.put("q42", Q42_SETTER);
SETTER_MAP.put("q43", Q43_SETTER);
SETTER_MAP.put("q44", Q44_SETTER);
SETTER_MAP.put("q45", Q45_SETTER);
SETTER_MAP.put("q46", Q46_SETTER);
SETTER_MAP.put("q47", Q47_SETTER);
SETTER_MAP.put("q48", Q48_SETTER);
SETTER_MAP.put("q49", Q49_SETTER);
SETTER_MAP.put("q50", Q50_SETTER);
SETTER_MAP.put("q51", Q51_SETTER);
SETTER_MAP.put("q52", Q52_SETTER);
SETTER_MAP.put("q53", Q53_SETTER);
SETTER_MAP.put("q54", Q54_SETTER);
SETTER_MAP.put("q55", Q55_SETTER);
SETTER_MAP.put("q56", Q56_SETTER);
SETTER_MAP.put("q57", Q57_SETTER);
SETTER_MAP.put("q58", Q58_SETTER);
SETTER_MAP.put("q59", Q59_SETTER);
SETTER_MAP.put("q60", Q60_SETTER);
SETTER_MAP.put("q61", Q61_SETTER);
SETTER_MAP.put("q62", Q62_SETTER);
SETTER_MAP.put("q63", Q63_SETTER);
SETTER_MAP.put("q64", Q64_SETTER);
SETTER_MAP.put("q65", Q65_SETTER);
SETTER_MAP.put("q66", Q66_SETTER);
SETTER_MAP.put("q67", Q67_SETTER);
SETTER_MAP.put("q68", Q68_SETTER);
SETTER_MAP.put("q69", Q69_SETTER);
SETTER_MAP.put("q70", Q70_SETTER);
SETTER_MAP.put("q71", Q71_SETTER);
SETTER_MAP.put("q72", Q72_SETTER);
SETTER_MAP.put("q73", Q73_SETTER);
SETTER_MAP.put("q74", Q74_SETTER);
SETTER_MAP.put("q75", Q75_SETTER);
SETTER_MAP.put("q76", Q76_SETTER);
SETTER_MAP.put("q77", Q77_SETTER);
SETTER_MAP.put("q78", Q78_SETTER);
SETTER_MAP.put("q79", Q79_SETTER);
SETTER_MAP.put("q80", Q80_SETTER);
SETTER_MAP.put("q81", Q81_SETTER);
SETTER_MAP.put("q82", Q82_SETTER);
SETTER_MAP.put("q83", Q83_SETTER);
SETTER_MAP.put("q84", Q84_SETTER);
SETTER_MAP.put("q85", Q85_SETTER);
SETTER_MAP.put("q86", Q86_SETTER);
SETTER_MAP.put("q87", Q87_SETTER);
SETTER_MAP.put("q88", Q88_SETTER);
SETTER_MAP.put("q89", Q89_SETTER);
SETTER_MAP.put("q90", Q90_SETTER);
SETTER_MAP.put("q91", Q91_SETTER);
SETTER_MAP.put("q92", Q92_SETTER);
SETTER_MAP.put("q93", Q93_SETTER);
SETTER_MAP.put("q94", Q94_SETTER);
SETTER_MAP.put("q95", Q95_SETTER);
SETTER_MAP.put("q96", Q96_SETTER);
GETTER_MAP = new HashMap<>(96);
GETTER_MAP.put("q1", QuarterData::getQ1);
GETTER_MAP.put("q2", QuarterData::getQ2);
GETTER_MAP.put("q3", QuarterData::getQ3);
GETTER_MAP.put("q4", QuarterData::getQ4);
GETTER_MAP.put("q5", QuarterData::getQ5);
GETTER_MAP.put("q6", QuarterData::getQ6);
GETTER_MAP.put("q7", QuarterData::getQ7);
GETTER_MAP.put("q8", QuarterData::getQ8);
GETTER_MAP.put("q9", QuarterData::getQ9);
GETTER_MAP.put("q10", QuarterData::getQ10);
GETTER_MAP.put("q11", QuarterData::getQ11);
GETTER_MAP.put("q12", QuarterData::getQ12);
GETTER_MAP.put("q13", QuarterData::getQ13);
GETTER_MAP.put("q14", QuarterData::getQ14);
GETTER_MAP.put("q15", QuarterData::getQ15);
GETTER_MAP.put("q16", QuarterData::getQ16);
GETTER_MAP.put("q17", QuarterData::getQ17);
GETTER_MAP.put("q18", QuarterData::getQ18);
GETTER_MAP.put("q19", QuarterData::getQ19);
GETTER_MAP.put("q20", QuarterData::getQ20);
GETTER_MAP.put("q21", QuarterData::getQ21);
GETTER_MAP.put("q22", QuarterData::getQ22);
GETTER_MAP.put("q23", QuarterData::getQ23);
GETTER_MAP.put("q24", QuarterData::getQ24);
GETTER_MAP.put("q25", QuarterData::getQ25);
GETTER_MAP.put("q26", QuarterData::getQ26);
GETTER_MAP.put("q27", QuarterData::getQ27);
GETTER_MAP.put("q28", QuarterData::getQ28);
GETTER_MAP.put("q29", QuarterData::getQ29);
GETTER_MAP.put("q30", QuarterData::getQ30);
GETTER_MAP.put("q31", QuarterData::getQ31);
GETTER_MAP.put("q32", QuarterData::getQ32);
GETTER_MAP.put("q33", QuarterData::getQ33);
GETTER_MAP.put("q34", QuarterData::getQ34);
GETTER_MAP.put("q35", QuarterData::getQ35);
GETTER_MAP.put("q36", QuarterData::getQ36);
GETTER_MAP.put("q37", QuarterData::getQ37);
GETTER_MAP.put("q38", QuarterData::getQ38);
GETTER_MAP.put("q39", QuarterData::getQ39);
GETTER_MAP.put("q40", QuarterData::getQ40);
GETTER_MAP.put("q41", QuarterData::getQ41);
GETTER_MAP.put("q42", QuarterData::getQ42);
GETTER_MAP.put("q43", QuarterData::getQ43);
GETTER_MAP.put("q44", QuarterData::getQ44);
GETTER_MAP.put("q45", QuarterData::getQ45);
GETTER_MAP.put("q46", QuarterData::getQ46);
GETTER_MAP.put("q47", QuarterData::getQ47);
GETTER_MAP.put("q48", QuarterData::getQ48);
GETTER_MAP.put("q49", QuarterData::getQ49);
GETTER_MAP.put("q50", QuarterData::getQ50);
GETTER_MAP.put("q51", QuarterData::getQ51);
GETTER_MAP.put("q52", QuarterData::getQ52);
GETTER_MAP.put("q53", QuarterData::getQ53);
GETTER_MAP.put("q54", QuarterData::getQ54);
GETTER_MAP.put("q55", QuarterData::getQ55);
GETTER_MAP.put("q56", QuarterData::getQ56);
GETTER_MAP.put("q57", QuarterData::getQ57);
GETTER_MAP.put("q58", QuarterData::getQ58);
GETTER_MAP.put("q59", QuarterData::getQ59);
GETTER_MAP.put("q60", QuarterData::getQ60);
GETTER_MAP.put("q61", QuarterData::getQ61);
GETTER_MAP.put("q62", QuarterData::getQ62);
GETTER_MAP.put("q63", QuarterData::getQ63);
GETTER_MAP.put("q64", QuarterData::getQ64);
GETTER_MAP.put("q65", QuarterData::getQ65);
GETTER_MAP.put("q66", QuarterData::getQ66);
GETTER_MAP.put("q67", QuarterData::getQ67);
GETTER_MAP.put("q68", QuarterData::getQ68);
GETTER_MAP.put("q69", QuarterData::getQ69);
GETTER_MAP.put("q70", QuarterData::getQ70);
GETTER_MAP.put("q71", QuarterData::getQ71);
GETTER_MAP.put("q72", QuarterData::getQ72);
GETTER_MAP.put("q73", QuarterData::getQ73);
GETTER_MAP.put("q74", QuarterData::getQ74);
GETTER_MAP.put("q75", QuarterData::getQ75);
GETTER_MAP.put("q76", QuarterData::getQ76);
GETTER_MAP.put("q77", QuarterData::getQ77);
GETTER_MAP.put("q78", QuarterData::getQ78);
GETTER_MAP.put("q79", QuarterData::getQ79);
GETTER_MAP.put("q80", QuarterData::getQ80);
GETTER_MAP.put("q81", QuarterData::getQ81);
GETTER_MAP.put("q82", QuarterData::getQ82);
GETTER_MAP.put("q83", QuarterData::getQ83);
GETTER_MAP.put("q84", QuarterData::getQ84);
GETTER_MAP.put("q85", QuarterData::getQ85);
GETTER_MAP.put("q86", QuarterData::getQ86);
GETTER_MAP.put("q87", QuarterData::getQ87);
GETTER_MAP.put("q88", QuarterData::getQ88);
GETTER_MAP.put("q89", QuarterData::getQ89);
GETTER_MAP.put("q90", QuarterData::getQ90);
GETTER_MAP.put("q91", QuarterData::getQ91);
GETTER_MAP.put("q92", QuarterData::getQ92);
GETTER_MAP.put("q93", QuarterData::getQ93);
GETTER_MAP.put("q94", QuarterData::getQ94);
GETTER_MAP.put("q95", QuarterData::getQ95);
GETTER_MAP.put("q96", QuarterData::getQ96);
}
public void set(List<BigDecimal> decimals, BigDecimal price) {
if (CollectionUtil.isNotEmpty(decimals)) {
BigDecimal totalDecimal = MathOperateUtil.sumList(decimals);
this.setTotalPower(totalDecimal);
if (Objects.nonNull(price)) {
this.setTotalFee(MathOperateUtil.MULTI_OP.operate(totalDecimal, price));
}
for (int i = 0; i < decimals.size(); i++) {
String key = "q" + (i + 1);
DtoSetter<BigDecimal, QuarterData> setter = SETTER_MAP.get(key);
if (Objects.nonNull(setter)) {
setter.set(decimals.get(i), this);
}
}
}
}
@JsonIgnore
@JSONField(serialize = false, deserialize = false)
public List<BigDecimal> get96Points() {
List<BigDecimal> list = new ArrayList<>(96);
int index = 1;
for (String quarter :TimePointUtil.getQUARTERLIST()) {
String key = "q" + index;
Function<QuarterData, BigDecimal> getter = GETTER_MAP.get(key);
if (Objects.nonNull(getter)) {
list.add(getter.apply(this));
}
index++;
}
return list;
}
由于都是重复代码,就用main方法去生成吧。把字段名与具体的getter或者setter添加到map中,后面把这个对象的多属性值的set与get方法封装各一个。
其中setter方法是自定义接口,代码如下
@FunctionalInterface
public interface DtoSetter<T, E> {
void set(T value, E target);
}
这样就解决了情况1,情况2的问题。
业务逻辑扩散
说明:这里以一个简单的例子来说明
代码如下
public class StrategyDemo {
public static final Map<String, Strategyer> DOS_MAP;
public static final Strategyer THING_1 = System.out::println;
public static final Strategyer THING_2 = name -> {
System.out.println("这是第二件事");
System.out.printf("第二件事的名字是{}", name);
};
static {
DOS_MAP = new HashMap<>();
DOS_MAP.put("1", THING_1);
DOS_MAP.put("2", THING_2);
}
public static void main(String[] args) {
// 这个假设是方法传进来的一个参数
String param = "1";
Strategyer strategyer = DOS_MAP.get(param);
if (Objects.nonNull(strategyer)) {
strategyer.doSomething("okkkkk");
}
}
@FunctionalInterface
public interface Strategyer {
/**
* 接口方法
*
* @param name 名字
*/
void doSomething(String name);
}
}
建议以上Map对应的策略Key可以使用枚举去控制。这样就实现参数控制业务逻辑的作用。
不同的程序入口,相同的处理逻辑
说明:有几个接口是用于往远端推送数据用的,在执行逻辑前都需要获取验证信息,获取http连接,但是获取的数据接口又不同;所以这些接口写到一个公有的方法里,以参数的形式把获取数据的逻辑区分开来。
(1)业务接口代码
void pushPeriodData(LocalDate date);
void pushDayData(LocalDate date);
void pushMonthData(LocalDate date);
这三个接口获取不同的参数后,进入同一个方法,代码如下
(2)公用业务入口
/**
* 公共接口
*
* @param apiEnum 不同接口信息枚举
* @param getPushData 获取不同数据的策略接口
* @param date 日期
*/
void pushData(GroupPushApiEnum apiEnum, GetPushData getPushData, LocalDate date)
(3)获取数据策略接口,代码如下
@FunctionalInterface
private interface GetPushData {
/**
* 获取数据接口
*
* @param date 日期
* @param osOrgId id
* @param provinceId 省id
* @return 数据
*/
GroupPushBaseDto get(LocalDate date, String osOrgId, String provinceId);
}
private final GetPushData periodDataGetter = (date, osOrgId, provinceId) -> powerDayOutputReportService.getGroupPushPeriodData(date, osOrgId, provinceId);
private final GetPushData dayDataGetter = (date, osOrgId, provinceId) -> powerDayOutputReportService.getGroupPushDayData(date, osOrgId, provinceId);
private final GetPushData monthDataGetter = (date, osOrgId, provinceId) -> {
LocalDate startDate = date.with(TemporalAdjusters.firstDayOfMonth());
LocalDate endDate = date.with(TemporalAdjusters.lastDayOfMonth());
return powerDayOutputReportService.getGroupPushMonthData(startDate, endDate, osOrgId, provinceId);
};
其他例子
(1)逐项计算List数据
场景:对List中的数据做加减乘除运算
代码:
/**
* 聚合 两个list,逐项
*
* @param list1 第一个list
* @param list2 第二个list
* @return 聚合结果
*/
public static List<BigDecimal> operateList(List<BigDecimal> list1, List<BigDecimal> list2, Operator<BigDecimal, BigDecimal> operator) {
if (CollectionUtils.isEmpty(list1) && CollectionUtils.isEmpty(list2)) {
return Collections.emptyList();
}
int len = CollectionUtils.isEmpty(list2) ? list1.size() : CollectionUtils.isEmpty(list1) ? list2.size() : Math.max(list1.size(), list2.size());
List<BigDecimal> result = new ArrayList<>();
for (int i = 0; i < len; i++) {
BigDecimal decimal1 = null;
BigDecimal decimal2 = null;
if (Objects.nonNull(list1) && list1.size() > i) {
decimal1 = list1.get(i);
}
if (Objects.nonNull(list2) && list2.size() > i) {
decimal2 = list2.get(i);
}
result.add(operator.operate(decimal1, decimal2));
}
return result;
}
public static final Operator<BigDecimal, BigDecimal> ADD_OP = (v1, v2) -> {
if (Objects.nonNull(v1) && Objects.nonNull(v2)) {
return v1.add(v2);
} else {
return Objects.nonNull(v1) ? v1 : v2;
}
};
public static final Operator<BigDecimal, BigDecimal> SUB_OP = (v1, v2) -> {
if (Objects.nonNull(v1) && Objects.nonNull(v2)) {
return v1.subtract(v2);
} else {
return Objects.nonNull(v1) ? v1 : Objects.nonNull(v2) ? v2.negate() : null;
}
};
public static final Operator<BigDecimal, BigDecimal> RATIO_OP = (v1, v2) -> {
if (Objects.nonNull(v1) && Objects.nonNull(v2)) {
if (BigDecimal.ZERO.compareTo(v1) == 0 && BigDecimal.ZERO.compareTo(v2) == 0) {
return BigDecimal.ZERO;
}
if (BigDecimal.ZERO.compareTo(v2) != 0) {
return v1.divide(v2, 10, BigDecimal.ROUND_HALF_UP);
}
}
return null;
};
public static final Operator<BigDecimal, BigDecimal> MULTI_OP = (v1, v2) -> {
if (Objects.nonNull(v1) && Objects.nonNull(v2)) {
return v1.multiply(v2);
} else {
return null;
}
};
@FunctionalInterface
public interface Operator<V1 extends Number, V2 extends Number> {
/**
* 数值运算接口
*
* @param v1 第一个值
* @param v2 第二个值
* @return 结果
*/
BigDecimal operate(V1 v1, V2 v2);
}
使用:
List<BigDecimal> inFee = MathOperateUtil.operateList(inPrice, inElec, MathOperateUtil.MULTI_OP);
(2)实现数值区间
场景:有时候我们判断一种情况需要根据数据的数值区间去区分不同类型
代码:
@FunctionalInterface
public interface Somparator<V extends Comparable<V>> {
/**
* 变量比较
*
* @param v1 第一个值
* @param v2 第二个值
* @return 比较结果
*/
boolean compare(V v1, V v2);
}
/**
* LocalTime等于
*/
public static final MathOperateUtil.Somparator<LocalTime> EQUAL = (v1, v2) -> {
if (Objects.isNull(v1) || Objects.isNull(v2)) {
throw new BaseException(EPowerResultCode.COMPUTE_INCOME_FAIL);
}
return v1.compareTo(v2) == 0;
};
/**
* LocalTime小于等于 零点默认为次日零点所以是最大时点
*/
public static final MathOperateUtil.Somparator<LocalTime> LESS_EQUAL = (v1, v2) -> {
if (Objects.isNull(v1) || Objects.isNull(v2)) {
throw new BaseException(EPowerResultCode.COMPUTE_INCOME_FAIL);
}
if (v1.compareTo(v2) == 0 || ZERO_TIME.compareTo(v2) == 0) {
return true;
}
if (ZERO_TIME.compareTo(v1) == 0) {
return false;
}
return v1.compareTo(v2) < 0;
};
/**
* LocalTime大于等于 零点默认为次日零点所以是最大时点
*/
public static final MathOperateUtil.Somparator<LocalTime> GREAT_EQUAL = (v1, v2) -> {
if (Objects.isNull(v1) || Objects.isNull(v2)) {
throw new BaseException(EPowerResultCode.COMPUTE_INCOME_FAIL);
}
if (v1.compareTo(v2) == 0 || ZERO_TIME.compareTo(v1) == 0) {
return true;
}
if (ZERO_TIME.compareTo(v2) == 0) {
return false;
}
return v1.compareTo(v2) > 0;
};
/**
* LocalTime小于 零点默认为次日零点所以是最大时点
*/
public static final MathOperateUtil.Somparator<LocalTime> LESS = (v1, v2) -> {
if (Objects.isNull(v1) || Objects.isNull(v2)) {
throw new BaseException(EPowerResultCode.COMPUTE_INCOME_FAIL);
}
if (ZERO_TIME.compareTo(v1) == 0) {
return false;
}
if (ZERO_TIME.compareTo(v2) == 0) {
return true;
}
return v1.compareTo(v2) < 0;
};
/**
* LocalTime大于 零点默认为次日零点所以是最大时点
*/
public static final MathOperateUtil.Somparator<LocalTime> GREAT = (v1, v2) -> {
if (Objects.isNull(v1) || Objects.isNull(v2)) {
throw new BaseException(EPowerResultCode.COMPUTE_INCOME_FAIL);
}
if (ZERO_TIME.compareTo(v1) == 0) {
return true;
}
if (ZERO_TIME.compareTo(v2) == 0) {
return false;
}
return v1.compareTo(v2) > 0;
};
/**
* LocalTime不等于
*/
public static final MathOperateUtil.Somparator<LocalTime> NOT_EQUAL = (v1, v2) -> {
if (Objects.isNull(v1) || Objects.isNull(v2)) {
throw new BaseException(EPowerResultCode.COMPUTE_INCOME_FAIL);
}
return v1.compareTo(v2) != 0;
};
使用:
/**
* 规定时间段类型 第一段(00:00-06:00] 零点规定为当天最后一个点,故第一段从0:1:0开始
*/
NUM1_SCOPE(1, "第一段", TimeUtil.GREAT_EQUAL, TimeUtil.ONE_TIME, LocalTime.of(6, 0 ,0), TimeUtil.LESS_EQUAL),
/**
* 规定时间段类型 第二段(06:00-10:00]
*/
NUM2_SCOPE(2, "第二段", TimeUtil.GREAT, LocalTime.of(6, 0 ,0), LocalTime.of(10, 0 ,0), TimeUtil.LESS_EQUAL),
/**
* 规定时间段类型 第三段(10:00-15:00]
*/
NUM3_SCOPE(3, "第三段", TimeUtil.GREAT, LocalTime.of(10, 0 ,0), LocalTime.of(15, 0 ,0), TimeUtil.LESS_EQUAL),
/**
* 规定时间段类型 第四段(15:00-17:00]
*/
NUM4_SCOPE(4, "第四段", TimeUtil.GREAT, LocalTime.of(15, 0 ,0), LocalTime.of(17, 0 ,0), TimeUtil.LESS_EQUAL),
/**
* 规定时间段类型 第五段(17:00-22:00]
*/
NUM5_SCOPE(5, "第五段", TimeUtil.GREAT, LocalTime.of(17, 0 ,0), LocalTime.of(22, 0 ,0), TimeUtil.LESS_EQUAL),
/**
* 规定时间段类型 第六段(22:00-24:00]
*/
NUM6_SCOPE(6, "第六段", TimeUtil.GREAT, LocalTime.of(22, 0 ,0), LocalTime.of(0, 0 ,0), TimeUtil.LESS_EQUAL)
总结
至此,我们就总结了一些实际开发中比较有用的使用策略模式的场景,我们可以看到,这几类其实都是一样的实现,事先写好的逻辑放到Map中或者注入不同的接口中,从而从更细的粒度去控制一个方法内的行为(有些编程语言有元函数的语法)。