如何优雅的消灭if...else...代码

其实我们都钟爱if...else    

       if...else...在我们的代码中很常见,一遇到逻辑判断,我们基本第一个会想到它(应该不止我一个人更钟爱于if...else...,而很少使用switch...case..吧)。的确,if...else...确实很好用,但是如果多层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...代码_第1张图片

嗯,这还是航天飞机模式,这是改代码的时候,你懂得......

 

      在通常情况下,对于if...else...语句,我们会使用switch....case...或者策略模式实现(确实是可以减少判断次数)。但是总感觉实现不是很优雅,业务变动时,还是要改动代码,那么有什么有更好的一种的方法呢?

     我们可以看到从if...else...到switch...case和策略模式,本质是将多层判断转换成了key-->value的形式。Map也是key-->value

的结构,能不能把类型和具体实现的方法注入map,这样的话,整个逻辑看起来会异常清晰,有多少种类型就有多少个key和多少种实现。

1. 定义抽象类,指定场景类型以及该场景需要执行的行为

public abstract class TaskSolver {

  public abstract void solve();

  public abstract String[] supports();

}

2. 定义各种场景的枚举

public enum TaskType {

  MORNING_EIGHT,

  MORNING_ELEVEN,

  AFTERNOON_TWO,

  AFTERNOON_FOUR,

  AFTERNOON_SIX,

  AFTERNOON_NINE,

  AFTERNOON_ELEVEN;

}

3. 指定具体场景类型以及要实现的行为

@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()};
  }
}

这里就不全部列举了,其他情形也是这样的....

4. 在Spring容器启动的时候,加载bean时,将类型和实现注入容器

@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;
  }

}

   就这样,全局没有一个判断,依然实现了不同逻辑下的具体行为执行,而且代码看起来还这么优雅。

你可能感兴趣的:(如何优雅的消灭if...else...代码)