成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

設計模式之責任鏈模式

開發 前端
給多個對象處理請求的機會,減少請求的發送者與接受者之間的耦合。將接受對象鏈接起來,在鏈中傳遞請求,直到有一個對象處理這個請求。

[[441814]]

簡介

定義:給多個對象處理請求的機會,減少請求的發送者與接受者之間的耦合。將接受對象鏈接起來,在鏈中傳遞請求,直到有一個對象處理這個請求。 

速記:責任傳遞 

案例:財務報銷、擊鼓傳花、Sentinel(CtSph.java)、Zookeeper、Nacos

我考慮對創建訂單的流程通過責任鏈模式的方式進行重構,先來看看我創建訂單的流程。

創建訂單 -> 消耗優惠券 -> 發貨 -> 返利

環境介紹:

jdk 1.8 , spring 5.2.x

代碼實現

代碼實現如下圖所示,通過 AbstractOrderHandler 定義抽象的接口,規范 Handler 的行為,在我的場景下有 4 個 Handler : 1、CreateOrderHandler 創建訂單。2、UseCouponOrderHandler 使用優惠券 3、GoodsDeliverOrderHandler 商品發貨 4、RebateOrderHandler 營銷返現 通過這樣的設計我們就可以巧妙的,將繁雜的流程,進行水平拆分為 Handler ,將之前的 BIG Method ,拆分成了一個可以復用的低耦合的類文件。下面是一個類的示意圖:

定義抽象方法

AbstractOrderHandler 定義如下,主要是有兩個作用,定義 doHandle 抽象方法,以及為后期按照類型區分 Handler 業務的的 getTypeEnum 方法。

  1. public abstract class AbstractOrderHandler { 
  2.  
  3.     /** 
  4.      * 區分類型 
  5.      * 
  6.      * @return 
  7.      */ 
  8.     protected abstract OrderTypeEnum getTypeEnum(); 
  9.  
  10.     /** 
  11.      * 核心處理 
  12.      * 
  13.      * @param context 上下文 
  14.      * @param args    拓展參數 
  15.      */ 
  16.     public void doHandle(OrderHandleContext context, 
  17.                          OrderHandlerChain chain, Object... args) { 
  18.         // 我是否可以處理 
  19.         if (Objects.isNull(getTypeEnum()) ||  
  20.             Objects.equals(context.getTypeEnum(), getTypeEnum())) { 
  21.             // 讓我來處理 
  22.             doHandle(context, args); 
  23.         } 
  24.         // 我處理完了,交給下家 
  25.         chain.handle(context, args); 
  26.     } 
  27.  
  28.     /** 
  29.      * 具體業務處理 
  30.      * 
  31.      * @param context 
  32.      * @param args 
  33.      */ 
  34.     protected abstract void doHandle(OrderHandleContext context, Object... args); 
  35.  

責任鏈的實現

具體的 Handler 實現,這里我列舉了兩個 Handler 的代碼,分別是 CreateOrderHandler 創建訂單、RebateOrderHandler 營銷返利。核心邏輯即使實現 AbstractOrderHandler 接口,并且實現內部的細分邏輯。

  1. // 創建訂單 
  2. @Slf4j 
  3. @Service 
  4. @Order(100) 
  5. public class CreateOrderHandler extends AbstractOrderHandler { 
  6.  
  7.     @Override 
  8.     protected OrderTypeEnum getTypeEnum() { 
  9.         return null
  10.     } 
  11.      
  12.     @Override 
  13.     protected void doHandle(OrderHandleContext context, Object... args) { 
  14.         log.info("default create order ... "); 
  15.  
  16.         // 鎖定庫存 
  17.         lockSku(context, args); 
  18.          
  19.         // 保存訂單 
  20.         saveOrder(context); 
  21.          
  22.         // 扣除庫存 
  23.         deductSku(context, args) 
  24.     } 
  25.  
  26.  
  27. // 訂單反現金 
  28. @Service 
  29. @Slf4j 
  30. @Order(200) 
  31. public class RebateOrderHandler extends AbstractOrderHandler { 
  32.  
  33.     @Override 
  34.     protected OrderTypeEnum getTypeEnum() { 
  35.         return null
  36.     } 
  37.  
  38.     @Override 
  39.     protected void doHandle(OrderHandleContext context, Object... args) { 
  40.         log.info("default rebate order ... "); 
  41.     } 

定義調用入口

OrderHandlerChain 是外部調用的入口,其實它主要的作用就是獲取 AbstractOrderHandler 并且排序(即串聯/編排 Handler ) 然后進行執行。這里我充分使用了 Spring 的 Bean 排序功能,通過在 Handler 上面定義 @Order 注解并且傳入順序值,我們在 @Autowired 獲取 List 的時候,Spring 會給我自動注入排好序的 handlerList 。

  1. @Slf4j 
  2. @Component 
  3. public class OrderHandlerChain { 
  4.  
  5.     @Autowired 
  6.     private List<AbstractOrderHandler> chain; 
  7.     @Autowired 
  8.     private ApplicationContext applicationContext; 
  9.  
  10.     public void handle(OrderHandleContext context, Object... objects) { 
  11.         if (context.getPos() < chain.size()) { 
  12.             AbstractOrderHandler handler = chain.get(context.getPos()); 
  13.             // 移動位于處理器鏈中的位置 
  14.             context.setPos(context.getPos() + 1); 
  15.             handler.doHandle(context, this, objects); 
  16.         } 
  17.     } 
  18.  

業務拓展

如果我的訂單邏輯發生變化,需要支持汽車訂單的創建和兼容。我們可以增加 Car 處理的 handler 通過指定不同 OrderTypeEnum 進行處理,如果你不想創建更多的 handler 類文件也可以通過 @Bean 來進行實現。

這里其實也是一種妥協的方式,其實和直接實現 AbstractOrderHandler 并沒有什么區別,都會生成 .class 文件,只是說在開發側來看少了一個 Java 文件而已,也會占 JVM 的 Metaspace 空間。

如下所示:

  1. @Configuration 
  2. public class CarOrderHandlers { 
  3.  
  4.     /** 
  5.      * 汽車訂單創建 
  6.      * 
  7.      * @return 
  8.      */ 
  9.     @Bean(name = "createOrderByCar"
  10.     public AbstractOrderHandler createOrderByCar() { 
  11.         return new CreateOrderHandler() { 
  12.             @Override 
  13.             protected OrderTypeEnum getTypeEnum() { 
  14.                 return OrderTypeEnum.Car; 
  15.             } 
  16.  
  17.             @Autowired 
  18.             private ApplicationContext applicationContext; 
  19.  
  20.             @Override 
  21.             protected void doHandle(OrderHandleContext context, Object... args) { 
  22.                 System.out.println("car order create ...."); 
  23.             } 
  24.         }; 
  25.     } 
  26.  

測試代碼

測試代碼如下,我們只需要傳入一個 Context 對象然后調用 chain.handle 方法即可。

  1. @Slf4j 
  2. @SpringBootTest(classes = App.class) 
  3. public class OrderHandlerChainTest { 
  4.  
  5.     @Resource 
  6.     private OrderHandlerChain chain; 
  7.  
  8.     @Test 
  9.     public void testOrderChain() { 
  10.  
  11.         OrderHandleContext context = new OrderHandleContext(); 
  12.         context.setTypeEnum(OrderTypeEnum.Car); 
  13.         chain.handle(context, null); 
  14.     } 

總結

本文主要是利用了 Spring 進行排序, Bean 定義等特征,實現責任鏈。感覺改造過后,有一點策略 + 模板 的感覺。策略模式主要是運用: 多方案切換的場景對業務進行垂直路由分別處理。責任鏈模式主要運用:責任傳遞的場景對業務進行水平分段處理粒度可以說更加細一些。

其實我們 JDK8 還提供了 @FunctionalInterface 函數接口,我們也可以將 AbstractOrderHandler 修改為 interface 接口,這樣我們就可以通過 lambda 表達式的方式注冊 Handler 其實本質都是一樣的。Over!歡迎大家留言交流。

參考文章

https://www.cnblogs.com/vcmq/p/12542399.html

http://c.biancheng.net/view/1383.html

 

責任編輯:武曉燕 來源: 運維開發故事
相關推薦

2010-04-01 09:10:03

PHP設計模式責任鏈模式

2012-03-28 13:28:56

Java設計模式

2023-06-05 07:55:31

2024-01-30 13:15:00

設計模式責任鏈

2020-11-17 09:32:57

設計模式責任鏈

2023-09-26 00:27:07

設計模式鏈接

2022-12-28 08:08:57

2021-08-14 08:17:49

Android設計模式OKHttp

2022-11-01 08:46:20

責任鏈模式對象

2024-05-09 12:17:00

責任鏈設計模式

2024-06-04 13:11:52

Python行為設計模式開發

2024-12-03 15:52:45

責任鏈Java

2021-07-14 10:08:30

責任鏈模式加工鏈

2021-06-05 17:59:00

責任鏈模式設計

2023-09-28 08:45:56

開源責任鏈模式

2020-08-21 07:23:50

工廠模式設計

2021-05-25 09:00:52

責任鏈模式設計模式面試經歷

2021-06-09 08:53:34

設計模式策略模式工廠模式

2012-02-29 09:41:14

JavaScript

2015-09-08 13:39:10

JavaScript設計模式
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 做a网站 | 青春草91| 久久网站免费视频 | 日韩精品免费播放 | 另类专区亚洲 | 亚洲综合无码一区二区 | 久久久久国产一区二区三区不卡 | 久久久久国产 | 91在线一区二区 | 久久婷婷国产香蕉 | 欧美一级在线免费观看 | 精品视频久久久 | 91精品久久久久久久 | 欧美黄在线观看 | 国产福利精品一区 | 欧美黄色免费网站 | 97精品超碰一区二区三区 | 国产精品一区二区三区在线 | 亚洲精品一区二区三区在线观看 | 亚洲欧洲日韩精品 中文字幕 | 精品国产乱码久久久久久丨区2区 | 亚洲精品国产成人 | 国产精品久久久久久一区二区三区 | 精品视频在线观看 | 亚洲国产精品一区二区第一页 | 欧美五月婷婷 | 日韩欧美精品 | 欧美一区二区三区在线看 | 一区二区三区中文字幕 | 国产麻豆乱码精品一区二区三区 | 99热在这里只有精品 | 国产一区二区不卡 | 日韩亚洲欧美一区 | 国产91在线 | 中日 | 91精品久久久久久久久久入口 | 成人毛片网站 | 欧美日韩一区二区三区四区 | 国产高清在线 | 夫妻午夜影院 | 91在线精品一区二区 | 一区二区福利视频 |