過多if - else 的問題, 以及策略模式 + 反射解決方法
阿新 • • 發佈:2021-03-10
1. 策略模式解決if - else 的程式碼
業務場景:
外包企業的審批人需要審批打卡的場景;
審批人分為多種不同的級別,多種級別中具有方式相同但是內容不同的操作:審批。
原來場景:
有前端傳來審批人蔘數,使用if-else 來判斷該審批人的級別屬於哪一個級別,執行相應的審批方法。每一個審批方法寫在了業務類底,命名採用1級審批,2級審批---等等的命名方式來命名。
問題:if - else 邏輯複雜,不易閱讀,函式中審批能抽象的地方未抽象,
兩個核心問題:test測試非常麻煩,新增審批人員需要對程式碼進行修改,違背開閉原則。
解決過程:
1. 抽象審批中的原子操作的程式碼,比如查詢對應級別所審批的同學名單。程式碼變得好看一些,但是任然未解決,if - else 和 多個 審批方法的實現。
2. 嘗試策略模式
1. 使用策略模式將每個級別的使用者抽象起來
2. ![](https://img2020.cnblogs.com/blog/1928212/202103/1928212-20210310201032932-973453746.png)
```java
package strategy;
public class Main {
public static void main(String[] args) {
if (LevelEnum.LEVEL1.equals(1)) {
SupervisorControl supervisorControl = new SupervisorControl(new Supervisor1());
supervisorControl.execute(1);
}
if (LevelEnum.LEVEL2.equals(2)) {
SupervisorControl supervisorControl = new SupervisorControl(new Supervisor2());
supervisorControl.execute(2);
}
if (LevelEnum.LEVEL3.equals(3)) {
SupervisorControl supervisorControl = new SupervisorControl(new Supervisor3());
supervisorControl.execute(3);
}
}
}
```
```java
package strategy;
public enum LevelEnum {
LEVEL1, LEVEL2, LEVEL3
}
```
```java
package strategy;
public interface Supervisor {
void examine(int supervisorId);
}
```
```java
package strategy;
public class Supervisor1 implements Supervisor {
public void examine(int supervisorId) {
System.out.println("去做一些和1級supervisor相關的工作");
}
}
```
```
package strategy;
public class Supervisor2 implements Supervisor {
public void examine(int supervisorId) {
System.out.println("去做一些和2級supervisor相關的工作");
}
}
```
```java
package strategy;
public class Supervisor3 implements Supervisor {
public void examine(int supervisorId) {
System.out.println("去做一些和3級supervisor相關的工作");
}
}
```
```java
package strategy;
public class SupervisorControl {
Supervisor supervisor;
public SupervisorControl(Supervisor supervisor) {
this.supervisor = supervisor;
}
public void execute(int id) {
supervisor.examine(id);
}
}
```
![](https://img2020.cnblogs.com/blog/1928212/202103/1928212-20210310201044119-98594275.png)
### 解決方法:
3. 混合使用策略模式和反射來解決
```Java
package strategy;
public class Main {
public static void main(String[] args) {
// if (LevelEnum.LEVEL1.equals(1)) {
// SupervisorControl supervisorControl = new SupervisorControl(new Supervisor1());
// supervisorControl.execute(1);
// }
// if (LevelEnum.LEVEL2.equals(2)) {
// SupervisorControl supervisorControl = new SupervisorControl(new Supervisor2());
// supervisorControl.execute(2);
// }
// if (LevelEnum.LEVEL3.equals(3)) {
// SupervisorControl supervisorControl = new SupervisorControl(new Supervisor3());
// supervisorControl.execute(3);
// }
String packageName = Supervisor1.class.getPackage().getName();
String supervisorName = packageName + "." + "Supervisor" + "2";
try {
Class clazz = Class.forName(supervisorName);
Supervisor supervisor = (Supervisor) clazz.newInstance();
supervisor.examine(1);
} catch (Exception e) {
System.out.println(e);
}
}
}
```
**注意**
class.forName() 需要傳入的格式是"包名.類名"。如果找不到包名則會報ClassNotFoundException
可以通過class.getPackage來獲取包名。
-------------------------------------------------------------------
到此我們解決了if - else 很多的問題,並且解決了需要侵入程式碼修改的問題,如果新增supervisor的級別,只需要和前端達成一致,後臺繼續寫一個supervisor4物件即可。
### 為什麼解決了test難的問題
對於test來說,每一個If-else 都需要我們去驗證,這其實就是兩個test, if 一個 else一個,如果有很多if - else,想要保證高的test覆蓋率,就會非常頭痛。
然而我們用策略模式 和 反射來解決,只需要,對主邏輯一個test,每一個實現方法做一個test即可。
至此,所有問題都解決了,程式碼一片