前端頁面會根據用戶選擇的下拉列表選項,傳給後端相應的 Value 值,後端根據不同的 Value 值執行不同的業務邏輯,大致如下:
public String getSqlForField(String field){
if ("AGE".equals(field)){
// genSqlForAge
} else if ("DATE".equals(field)){
// genSqlForDate
} else if ("REUSE".equals(field)){
// genSqlForReuse
} else
....
}
由於前端下拉選項都是固定的值,且不大會變。我這邊打算使用反射的方式實現,邏輯是:定義一個請求處理類 A,裏面的方法和前端下拉列表的值是一一對應的,請求轉發類 B 根據前端傳過來的具體的Value值,構建一個方法名,和請求處理類 A 的一個方法名精確匹配,利用反射的方式調用。這樣就沒有了 if/else 判斷了。
請求處理類 A 的樣子:
public class VarQueryBodyBuilder extends VarMapUtil {
// 用戶可以不選擇“屬性”,就是 NoSpecified
public String getNoSpecified(){
...
}
// 是否複用,復術,複查等
public String getReuse() {
...
}
// 診斷,檢測等的時間
public String getDate() {
...
}
// 診斷,檢測等的年齡
public String getAge() {
...
請求轉發類 B 是反射的實現主體代碼:
String methodName = "get" + StringUtils.capitalize(field);
logger.info("當前變量屬性的SQL拼接將要調用的方法名爲::" + methodName);
Class<? extends VarQueryBodyBuilder> clazz = vqb.getClass();
String sql = null;
try {
Method m = clazz.getDeclaredMethod(methodName);
sql = (String)m.invoke(vqb);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("自定義變量反射調用方法時出錯::" + e.getMessage());
}
可以看到,構建 methodName, 就是 get 加上前端傳過來的 Value 值首字符大寫,就可以對應到 VarQueryBodyBuilder 的一個方法上,如果新增了一個下拉列表選項,就需要在 VarQueryBodyBuilder 再添加一個對應方法,而請求轉發類 B 不用動,這樣就消除了 if/else 語句。