我的任务是处理一些代码,并且有一个巨大的if-else-if链(100+ else-ifs)检查字符串。
更新此代码有哪些好方法可以将if-else-if链缩小到更易于管理的内容。
链看起来像这样:
if(name.equals("abc")){
do something
} else if(name.equals("xyz")){
do something different
} else if(name.equals("mno")){
do something different
} ......
.....
else{
error
}
答案 0 :(得分:18)
您可以将每个分支中的代码提取到单独的方法,然后将这些方法转换为公共基本接口的实现(让我们称之为Handler
)。之后,您可以填写Map<String, Handler>
,只需查找并执行给定字符串的正确处理程序。
不幸的是,为接口实现100多个子类需要相当多的样板代码,但目前在Java中没有更简单的方法来实现这一点。将案例实现为Enum
的元素可能会有所帮助 - here is an example。理想的解决方案是使用闭包/ lambda,但是我们必须等到Java 8 ...
答案 1 :(得分:8)
一些选项/想法:
hashMap.get(name).doSomething();
namedObject.doSomething()
答案 2 :(得分:8)
使用Enums,您可以为每个实例设置一个方法。
public enum ActionEnum {
ABC {
@Override
void doSomething() {
System.out.println("Doing something for ABC");
}
},
XYZ {
@Override
void doSomething() {
System.out.println("Doing something for XYZ");
}
};
abstract void doSomething();
}
public class MyActionClass {
public void myMethod(String name) {
ActionEnum.valueOf("ABC").doSomething();
}
}
它仍然有点混乱(有100多个条目的大枚举,即使它只是调度),但可以避免HashMap初始化代码(在我看来,100 + puts也很混乱)。
另一种选择(出于文档目的)将是反思:
public interface Action {
void doSomething();
}
public class ABCAction implements Action {
@Override
public void doSomething() {
System.out.println("Doing something for ABC");
}
}
public class MyActionClass {
void doSomethingWithReflection(String name) {
try {
Class<? extends Action> actionClass = Class.
forName("actpck."+ name + "Action").asSubclass(Action.class);
Action a = actionClass.newInstance();
a.doSomething();
} catch (Exception e) {
// TODO Catch exceptions individually and do something useful.
e.printStackTrace();
}
}
}
每种方法都有权衡:
答案 3 :(得分:7)
就像Matt Ball在评论中所说,你可以使用命令模式。定义Runnable类的集合:
Runnable task1 = new Runnable() {
public void run() { /* do something */ }
};
Runnable task2 = // etc.
然后你可以使用钥匙上的地图来运行:
Map<String,Runnable> taskMap = new HashMap<String,Runnable>();
taskMap.put("abc", task1);
taskMap.put("xyz", task2);
// etc.
最后,将if-else链替换为:
Runnable task = taskMap.get(name);
if (task != null) {
task.run();
} else {
// default else action from your original chain
}
答案 4 :(得分:2)
您可以使用switch语句,但已在Java SE 7
中实现了带有String案例的Switch语句最佳解决方案是使用command pattern
答案 5 :(得分:0)
这是一个受欢迎的Arrow Anti-Pattern,杰夫在他的帖子here中讨论了一些处理这个问题的方法。