策略模式用在統一的入口,但需要根據某個類型判斷后續執行邏輯,例如我最近遇到的場景:我需要對接一個設備,前端請求我這邊,我再去和設備交互,但設備種類很多,各自有自己的接入規則!傳統代碼會變成if{}else{}面條代碼,而且擴展性不佳,如果后續新增了設備,需要去修改這里的代碼,非常不優雅~
閑話少說上代碼!
1.創建一個枚舉,包含所有策略
public enum StrategyEnums {STRATEGY_ONE("strategyOne", "策略1"),STRATEGY_TWO("strategyTwo", "策略2"),STRATEGY_THREE("strategyThree", "策略3");private String code;private String name;StrategyEnums(String code, String name) {this.code = code;this.name = name;}
}
2.創建一個接口,含執行方法
public interface StrategyService {void run();
}
3.創建3個策略的業務類,實現【StrategyService】接口
public class StrategyServiceImpl1 implements StrategyService{@Overridepublic void run() {System.out.println("運行策略1的業務代碼");}
}
4.創建工廠類,用于初始化各策略,提供獲取策略的靜態方法
public class StrategyFactory {static final Map<StrategyEnums, StrategyService> map = new HashMap<>();static {map.put(StrategyEnums.STRATEGY_ONE, new StrategyServiceImpl1());map.put(StrategyEnums.STRATEGY_TWO, new StrategyServiceImpl2());map.put(StrategyEnums.STRATEGY_THREE, new StrategyServiceImpl3());}public static StrategyService getStrategy(StrategyEnums strategyEnums) {return map.get(strategyEnums);}
}
5.創建控制器,對前端提供接口【可選】
@RestController("design")
public class DesignController {@GetMapping("strategy")public void strategyTest(StrategyEnums strategyEnums) {StrategyService strategy = StrategyFactory.getStrategy(strategyEnums);strategy.run();}
}
6.創建測試類,調用接口【可選】
@SpringBootTest
public class DesignTest {@AutowiredDesignController designController;/*** 策略模式測試*/@Testpublic void strategyTest() {designController.strategyTest(StrategyEnums.STRATEGY_ONE);designController.strategyTest(StrategyEnums.STRATEGY_TWO);designController.strategyTest(StrategyEnums.STRATEGY_THREE);}
}
為了方便演示,我是從測試方法里調用的接口,實際上可以用postman走接口執行,或在測試類里使用工廠直接調用。下面查看執行結果:
假設后續新增一個需要對接的設備,我只需要在枚舉增加一個類型,在工廠里初始化,然后創建一個新的策略,完成業務代碼即可,優雅!實在是優雅~