业务代码中,太多 if else 怎么办?
生活随笔
收集整理的這篇文章主要介紹了
业务代码中,太多 if else 怎么办?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前段時間,我將公司系統中的批量審單的功能進行了重構,用到了java的并發編程進行異步化處理,數據庫的樂觀鎖機制處理多線程并發更新數據。其中批量審單的業務處理涉及到多種任務類型,對應不同的業務方法進行處理,比如轉倉,轉快遞,添加贈品,刪除贈品,拆分訂單,批量駁回,批量作廢等等,其中就用到了策略模式。
if else模式
????????if?("BATCH_CHANGE_WAREHOUSE".equals(taskType))?{//批量轉倉邏輯}?else?if?("BATCH_CHANGE_SHIPPING".equals(taskType))?{//批量轉快遞邏輯}?else?if?("BATCH_REPLACE_ORDER_GOODS".equals(taskType))?{//批量替換訂單商品邏輯}?else?if?("BATCH_DELETE_ORDER_GOODS".equals(taskType))?{//批量刪除訂單商品邏輯}?else?if?("BATCH_ADD_MEMO".equals(taskType))?{//批量添加備注邏輯}?else?{//任務類型未知System.out.println("任務類型無法處理");}看起來,思路清晰,if,else分支也很清楚,但不覺得代碼很臃腫,維護起來麻煩嗎,尤其是其他人來接鍋的時候,連看下去的欲望都沒有了。這時候你需要用策略模式消除其中的if else,進行一下簡單的重構!
策略模式
1、首先抽象業務處理器
public?abstract?class?InspectionSolver?{public?abstract?void?solve(Long?orderId,?Long?userId);public?abstract?String[]?supports(); }2、將業務處理器和其支持處理的類型放到一個容器中,java里Map就是最常用的容器之一
@Component public?class?InspectionSolverChooser?implements?ApplicationContextAware{private?Map<String,?InspectionSolver>?chooseMap?=?new?HashMap<>();public?InspectionSolver?choose(String?type)?{return?chooseMap.get(type);}@PostConstructpublic?void?register()?{Map<String,?InspectionSolver>?solverMap?=?context.getBeansOfType(InspectionSolver.class);for?(InspectionSolver?solver?:?solverMap.values())?{for?(String?support?:?solver.supports())?{chooseMap.put(support,solver);}}}private?ApplicationContext?context;@Overridepublic?void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException?{this.context=applicationContext;} }這里是在應用啟動的時候,加載spring容器中所有InspectionSolver類型的處理器,放到InspectionSolverChooser的map容器中。注意是InspectionSolver類型,所以定義的處理器都得繼承InspectionSolver,其次是spring容器中的才能加載,所以定義的處理器都得放到spring容器中(@Component注解不能少)
3、定義不同的處理器
@Component public?class?ChangeWarehouseSolver?extends?InspectionSolver?{@Overridepublic?void?solve(Long?orderId,?Long?userId)?{System.out.println("訂單"+orderId+"開始進行批量轉倉了。。");}@Overridepublic?String[]?supports()?{return?new?String[]?{InspectionConstant.INSPECTION_TASK_TYPE_BATCH_CHANGE_WAREHOUSE};} }@Component public?class?ChangeShippingSolver?extends?InspectionSolver{@Overridepublic?void?solve(Long?orderId,?Long?userId)?{System.out.println("訂單"+orderId+"開始進行轉快遞了。。");}@Overridepublic?String[]?supports()?{return?new?String[]?{InspectionConstant.INSPECTION_TASK_TYPE_BATCH_CHANGE_SHIPPING};} }@Component public?class?ReplaceOrderGoodsSolver?extends?InspectionSolver{@Overridepublic?void?solve(Long?orderId,?Long?userId)?{System.out.println("訂單"+orderId+"開始進行替換商品了");}@Overridepublic?String[]?supports()?{return?new?String[]{InspectionConstant.INSPECTION_TASK_TYPE_BATCH_REPLACE_ORDER_GOODS};} }4、測試類
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes=Application.class)//?指定spring-boot的啟動類 public?class?InspectionTest?{@Autowiredprivate?InspectionSolverChooser?chooser;@Testpublic?void?test()?throws?Exception{//準備數據String?taskType?=?InspectionConstant.INSPECTION_TASK_TYPE_BATCH_CHANGE_WAREHOUSE;Long?orderId?=?12345L;Long?userId?=?123L;//獲取任務類型對應的solverInspectionSolver?solver?=?chooser.choose(taskType);if?(solver?==?null)?{throw?new?RuntimeException("任務類型暫時無法處理!");}//調用不同solver的方法進行處理solver.solve(orderId,userId);} }在測試類中我消除了可能一長段的if else,從選擇器InspectionSolverChooser中根據type的不同取出不同的任務處理器InspectionSolver,然后調用其solve()方法進行任務處理,不同處理器調用的當然就是不同的solve()方法了,目的達到。
總結
以上是生活随笔為你收集整理的业务代码中,太多 if else 怎么办?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从架构到代码:软件开发最新趋势解析
- 下一篇: 为什么 wait/notify/noti