if...else...在我们的代码中很常见,一遇到逻辑判断,我们基本第一个会想到它(应该不止我一个人更钟爱于if...else...,而很少使用switch...case..吧)。的确,if...else...确实很好用,但是如果多层if...else嵌套在一起,看起来是不是很让人抓狂,尤其是看别人代码的,瞬间有一种想打人的冲动(if...else...确实很好用,但是我不想看别人的if...else代码,这种感觉有没有)
/**
* if-else 处理业务逻辑
*/
public void timeToDo(String time) {
if (TaskType.MORNING_EIGHT.toString().equalsIgnoreCase(time)) {
System.out.println("早上八点,该起床了!");
} else if (TaskType.MORNING_ELEVEN.toString().equalsIgnoreCase(time)) {
System.out.println("早上十一点了,离开工位休息一下吧!");
} else if (TaskType.AFTERNOON_TWO.toString().equalsIgnoreCase(time)) {
System.out.println("下午两点了,洗把脸准备上班吧!");
} else if (TaskType.AFTERNOON_FOUR.toString().equalsIgnoreCase(time)) {
System.out.println("下午四点了,休息下喝口水吧!");
} else if (TaskType.AFTERNOON_SIX.toString().equalsIgnoreCase(time)) {
System.out.println("下班时间到了,整理一下手中工作,回家陪陪家人吧!");
} else if (TaskType.AFTERNOON_NINE.toString().equalsIgnoreCase(time)) {
System.out.println("晚上九点了,要去洗漱了!");
} else if (TaskType.AFTERNOON_ELEVEN.toString().equalsIgnoreCase(time)) {
System.out.println("晚上十一点了,要睡觉了,不能在玩手机了!");
} else {
System.out.println("暂时没有安排,自己玩去吧");
}
}
现实中,我们大部分的if...else...都是这样,你可能觉得这样也没啥啊,逻辑也很清晰啊;接下来看一下这段代码:
嗯,这还是航天飞机模式,这是改代码的时候,你懂得......
在通常情况下,对于if...else...语句,我们会使用switch....case...或者策略模式实现(确实是可以减少判断次数)。但是总感觉实现不是很优雅,业务变动时,还是要改动代码,那么有什么有更好的一种的方法呢?
我们可以看到从if...else...到switch...case和策略模式,本质是将多层判断转换成了key-->value的形式。Map也是key-->value
的结构,能不能把类型和具体实现的方法注入map,这样的话,整个逻辑看起来会异常清晰,有多少种类型就有多少个key和多少种实现。
public abstract class TaskSolver {
public abstract void solve();
public abstract String[] supports();
}
public enum TaskType {
MORNING_EIGHT,
MORNING_ELEVEN,
AFTERNOON_TWO,
AFTERNOON_FOUR,
AFTERNOON_SIX,
AFTERNOON_NINE,
AFTERNOON_ELEVEN;
}
@Component
public class MorningEightSolver extends TaskSolver {
@Override
public void solve() {
System.out.println("早上八点,该起床了!");
}
@Override
public String[] supports() {
return new String[]{TaskType.MORNING_EIGHT.toString()};
}
}
@Component
public class MorningElvenSolver extends TaskSolver {
@Override
public void solve() {
System.out.println("早上十一点了,离开工位休息一下吧!");
}
@Override
public String[] supports() {
return new String[]{TaskType.MORNING_ELEVEN.toString()};
}
}
这里就不全部列举了,其他情形也是这样的....
@Component
public class TaskSolverChooser implements ApplicationContextAware {
private Map chooseMap = new HashMap<>();
private ApplicationContext context;
public TaskSolver choose(String type) {
return chooseMap.get(type);
}
@PostConstruct
public void register() {
Map solverMap = context.getBeansOfType(TaskSolver.class);
for (TaskSolver solver : solverMap.values()) {
for (String support : solver.supports()) {
chooseMap.put(support, solver);
}
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}
就这样,全局没有一个判断,依然实现了不同逻辑下的具体行为执行,而且代码看起来还这么优雅。