<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          業(yè)務代碼中,策略模式怎么用?

          共 4060字,需瀏覽 9分鐘

           ·

          2020-12-18 11:00

          點擊上方?泥瓦匠?輕松關注!

          及時獲取有趣有料的技術(shù)文章

          來源:juejin.im/post/5d12228de51d45775c73dd1b

          • if else模式
          • 策略模式
            • 1、首先抽象業(yè)務處理器
            • 2、將業(yè)務處理器和其支持處理的類型放到一個容器中,java里Map就是最常用的容器之一
            • 3、定義不同的處理器
            • 4、測試類

          前段時間,我將公司系統(tǒng)中的批量審單的功能進行了重構(gòu),用到了java的并發(fā)編程進行異步化處理,數(shù)據(jù)庫的樂觀鎖機制處理多線程并發(fā)更新數(shù)據(jù)。其中批量審單的業(yè)務處理涉及到多種任務類型,對應不同的業(yè)務方法進行處理,比如轉(zhuǎn)倉,轉(zhuǎn)快遞,添加贈品,刪除贈品,拆分訂單,批量駁回,批量作廢等等,其中就用到了策略模式。

          if else模式

          ????????if?("BATCH_CHANGE_WAREHOUSE".equals(taskType))?{
          ????????????//批量轉(zhuǎn)倉邏輯
          ????????}?else?if?("BATCH_CHANGE_SHIPPING".equals(taskType))?{
          ????????????//批量轉(zhuǎn)快遞邏輯
          ????????}?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,進行一下簡單的重構(gòu)!

          策略模式

          1、首先抽象業(yè)務處理器

          public?abstract?class?InspectionSolver?{

          ????public?abstract?void?solve(Long?orderId,?Long?userId);

          ????public?abstract?String[]?supports();
          }

          2、將業(yè)務處理器和其支持處理的類型放到一個容器中,java里Map就是最常用的容器之一

          @Component
          public?class?InspectionSolverChooser?implements?ApplicationContextAware{


          ????private?Map?chooseMap?=?new?HashMap<>();

          ????public?InspectionSolver?choose(String?type)?{
          ????????return?chooseMap.get(type);
          ????}

          ????@PostConstruct
          ????public?void?register()?{
          ????????Map?solverMap?=?context.getBeansOfType(InspectionSolver.class);
          ????????for?(InspectionSolver?solver?:?solverMap.values())?{
          ????????????for?(String?support?:?solver.supports())?{
          ????????????????chooseMap.put(support,solver);
          ????????????}
          ????????}
          ????}

          ????private?ApplicationContext?context;

          ????@Override
          ????public?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?{

          ????@Override
          ????public?void?solve(Long?orderId,?Long?userId)?{
          ????????System.out.println("訂單"+orderId+"開始進行批量轉(zhuǎn)倉了。。");
          ????}

          ????@Override
          ????public?String[]?supports()?{
          ????????return?new?String[]?{InspectionConstant.INSPECTION_TASK_TYPE_BATCH_CHANGE_WAREHOUSE};
          ????}
          }

          @Component
          public?class?ChangeShippingSolver?extends?InspectionSolver{

          ????@Override
          ????public?void?solve(Long?orderId,?Long?userId)?{
          ????????System.out.println("訂單"+orderId+"開始進行轉(zhuǎn)快遞了。。");
          ????}

          ????@Override
          ????public?String[]?supports()?{
          ????????return?new?String[]?{InspectionConstant.INSPECTION_TASK_TYPE_BATCH_CHANGE_SHIPPING};
          ????}
          }

          @Component
          public?class?ReplaceOrderGoodsSolver?extends?InspectionSolver{

          ????@Override
          ????public?void?solve(Long?orderId,?Long?userId)?{
          ????????System.out.println("訂單"+orderId+"開始進行替換商品了");
          ????}

          ????@Override
          ????public?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?{

          ????@Autowired
          ????private?InspectionSolverChooser?chooser;

          ????@Test
          ????public?void?test()?throws?Exception{
          ????????//準備數(shù)據(jù)
          ????????String?taskType?=?InspectionConstant.INSPECTION_TASK_TYPE_BATCH_CHANGE_WAREHOUSE;
          ????????Long?orderId?=?12345L;
          ????????Long?userId?=?123L;
          ????????//獲取任務類型對應的solver
          ????????InspectionSolver?solver?=?chooser.choose(taskType);
          ????????if?(solver?==?null)?{
          ????????????throw?new?RuntimeException("任務類型暫時無法處理!");
          ????????}
          ????????//調(diào)用不同solver的方法進行處理
          ????????solver.solve(orderId,userId);
          ????}
          }

          在測試類中我消除了可能一長段的if else,從選擇器InspectionSolverChooser中根據(jù)type的不同取出不同的任務處理器InspectionSolver,然后調(diào)用其solve()方法進行任務處理,不同處理器調(diào)用的當然就是不同的solve()方法了,目的達到。


          End


          歡迎加入知識星球,一起探討技術(shù)架構(gòu),交流技術(shù)人生。加入方式,長按下方二維碼
          已在知識星球更新如下:


          下方二維碼關注我

          互聯(lián)網(wǎng)草根,堅持分享技術(shù)、創(chuàng)業(yè)、產(chǎn)品心得和總結(jié)~



          點擊“閱讀原文”,領取 2020 年最新免費技術(shù)資料大全

          ↓↓↓
          瀏覽 57
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  乱伦综合肉 | 亚洲欧洲无码在线观看 | 亚洲男女激情 | 伊人黄色电影 | 一级大香蕉网站视频 |