前端页面会根据用户选择的下拉列表选项,传给后端相应的 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 语句。