【发布时间】:2014-01-17 14:03:10
【问题描述】:
我有一个 switch 语句,它将 String 与一组 String 进行比较,其中每个匹配调用不同的方法。
switch(((Operation) expr.getData()).getValue()){
case "+":
return add(expr.getNext());
case "car":
return car(expr.getNext());
case "cdr":
return cdr(expr.getNext());
case "cons":
return cons(expr.getNext(), expr.getNext().getNext());
case "quote":
return quote(expr.getNext());
case "define":
handleDefine(expr.getNext());
break;
default:
return null;
}
但是,对我来说,这听起来像是可以使用HashMap 更优雅、更有效地实现的东西,该HashMap 链接到包含Method 和参数数量的Operation,因此我可以使用每种方法来HashMap 喜欢:
nameToOperation.put("+", new Operation("+", 1, Driver.class.getMethod("add")));
nameToOperation.put("car", new Operation("car", 1, Driver.class.getMethod("car")));
所以会有N个不同的Operation类实例,每个实例包含String、Method和参数个数
然后我可以简单地使用类似于此的方法调用该方法(我知道这不是您使用调用的方式):
Operation op = ((Operation) expr.getData())
if(op.getNumPars() == 1)
return(op.getMethod().invoke(expr.getNext()));
else
return(op.getMethod().invoke(expr.getNext(), expr.getNext().getNext()));
但是,我仍然不完全喜欢这个解决方案,因为我正在失去类型安全性,而且它看起来仍然不是那么好。我在 stackoverflow 上看到的另一个看起来非常优雅但我不完全理解的示例是最佳答案的第一个解决方案:How to call a method stored in a HashMap? (Java)
Stackoverflow 上的每个人都认为最好的解决方案是什么?
编辑:以防万一有人搜索这个并想知道我的解决方案,我让每个操作,如 Add、Car、Cdr 都有自己的类来实现Command。然后我不得不让我的大部分方法都是静态的,我想它们本质上都是静态的。这似乎比原来的 case 语句更优雅。
【问题讨论】:
-
这似乎是 Action 或 Commannd Pattern 的用例。我在plugin application 中使用了这种模式来启用OSGi 类似的命令来通过控制台加载或卸载插件。命令在初始化到控制台后添加,甚至可以通过进一步动态加载的插件添加
-
我想说,如果您只在一个地方执行此操作,那么请坚持使用 switch 语句。使用反射或命令模式只会导致更多的代码行,而 imo 不会使代码更易于管理。但是,如果您在多个位置复制粘贴此 switch 语句(或此 switch 语句的一部分),那么情况就不同了,在这种情况下我会使用命令模式。
标签: java reflection methods hashmap switch-statement