目录

优化项目中大量 if...else...

在项目中经常会用 if..else… 去判断逻辑,当业务越来越复杂,一个逻辑会有大量的判断,如下面的代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
if(type.equals("o1")){
  // 执行 o1 逻辑
}else if(type.equals("o2")){
  // 执行 o2 逻辑
}else if(type.equals("o3")){
  // 执行 o3 逻辑
}else if(type.equals("o4")){
  // 执行 o4 逻辑
}else if(type.equals("o5")){
  // 执行 o5 逻辑
}

后面再增加逻辑 o6,o7… 一直到 o99 呢,这样写代码就会越写越长,后期越来越复杂,维护越来越难,嗯,已经闻到坏代码的味道,优化它。

首先想是否能通过设计模式来解决呢?

1. 策略模式

策略模式:一个类的行为或其他算法可以在运行时更改。这种类型的设计模式属于行为型模式。

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变 context 对象。策略对象改变 context 对象的执行算法。

关键词:实现同一个接口

那如何实现策略模式呢?

我们把上面大量 if…else… 的代码,用策略模式来实现下

1.1 首先创建一个接口

1
2
3
public interface Strategy{
  public void doSomething();
}

1.2. 实现接口的类

1
2
3
4
5
6
7
public class OperationO1 implements Strategy{
  
  @Override
  public void doSomething(){
    System.out.println("执行 o1 逻辑。");
  }
}
1
2
3
4
5
6
7
public class OperationO2 implements Strategy{
  
  @Override
  public void doSomething(){
    System.out.println("执行 o2 逻辑。");
  }
}
1
2
3
4
5
6
7
public class OperationO3 implements Strategy{
  
  @Override
  public void doSomething(){
    System.out.println("执行 o3 逻辑。");
  }
}

1.3. 创建 Context 类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class Conetext(){
  
  private Strategy strategy;
  
  public Conetext(Strategy strategy){
    this.strategy = strategy;
  }
  
  public void operation(){
    strategy.doSomething();
  }
}

1.4. 验证

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class Test{
  
  public static void main(String[] args){
    Conetext conetext = new Conetext(new OperationO1());
    conetext.operation();
    conetext = new Conetext(new OperationO2());
    conetext.operation();
    conetext = new Conetext(new OperationO3());
    conetext.operation();
  }
  
}
1
2
3
4
执行打印
执行 o1 逻辑。
执行 o2 逻辑。
执行 o3 逻辑。

ok,策略模式代码已经实现了,发现唉不对啊,这好像更 if…else 没有什么关系?下面来演示在项目中的实战。

2. 表驱动

这就要引出另一个词表驱动

表驱动法,又称之为表驱动、表驱动方法。 “表”是几乎所有数据结构课本都要讨论的非常有用的数据结构。表驱动方法出于特定的目的来使用表,程序员们经常谈到“表驱动”方法,但是课本中却从未提到过什么是"表驱动"方法。表驱动方法是一种使你可以在表中查找信息,而不必用很多的逻辑语句(if 或 Case)来把它们找出来的方法。事实上,任何信息都可以通过表来挑选。在简单的情况下,逻辑语句往往更简单而且更直接。但随着逻辑链的复杂,表就变得越来越富有吸引力了。

表驱动+策略模式

2.1. 新增策略管理类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Component
public class StrategyManager {

    private Map<String,Strategy> dispatcher = new HashMap<>();

    @PostConstruct
    private void initDispatcher(){
        dispatcher.put("o1",new OperationO1());
        dispatcher.put("o2",new OperationO2());
        dispatcher.put("o3",new OperationO3());
    }

    public void doStrategy(String type) throws Exception{
        Strategy strategy = dispatcher.get(type);
        if(strategy != null){
            strategy.doSomething();
        } else {
          throw new Exception("未找到业务策略。");  
        }
    }

}

2.2. 注入并使用

1
2
3
4
5
6
@Autowired
private StrategyManager strategyManager;

public void test(String type){
  strategyManager.doStrategy(type);
}

后期再添加新策略,只要在策略管理类中添加新增策略的实现类。

总结

最后记住一下秘诀

1
2
3
4
互斥条件表驱动,
嵌套条件校验链,
短路条件早 return,
零散条件可组合。