<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      不得不說,在很多業務中,這種模式用得真的很香

      故事

      “不能在寫if else來拓展當前系統了,現在已經有三個支付場景了......”工位上,小貓看著電腦,撓著頭。

      就在剛剛,小貓接到了一個新需求,需要和客戶公司打通資產,形成資產聯動。說白了就是需要定制化對接客戶公司的支付資產體系。除了這次接到的之外。前面其實已經對接了三家了。由于每家對接規范都不一樣,歷史對接的時候為了盡快上線,都是直接搞個else的新路由分支,然后去實現支付,退款。

      在小貓看來,就是在堆屎山。牽一發而動全身的感覺真的很不好。由于本次的需求留有的時間還是相當充裕的,所以小貓下定決心,打算利用這次的拓展,將原來不合理的地方用上設計模式將其重構掉。

      深思熟慮很久,小貓下定決心打算用“策略模式”重構一番。

      聊聊策略模式

      說到策略模式,老貓覺得這種設計模式在實際開發中使用其實是相當頻繁的。老貓工作到現在也在很多業務場景中使用過這樣的設計模式。例如,上述小貓遇到的第三方支付集成的問題上。另外的還有商城搞活動,針對不同的用戶下單行為提供不同的折扣或者返現等活動。再例如商城運營人員根據不同的加價策略去定在售商品的價格等。

      老貓工作十年中,對接過很多外部企業或者單位的接口,若業務定義一樣,只是接口協議不同的業務其實往往都可以用到策略模式。
      提煉一下適用場景如下:

      (1)系統中有很多類,而它們的區別僅僅在于行為不同。

      (2)一個系統需要動態地在幾種算法中選擇一種。

      在很多業務中,這種模式用起來真的很香,既能夠擺脫成堆的“if else”(當然關于 if else的優化,又是另外一個故事了,有興趣的小伙伴可以看看這篇文章【接手了個項目,被if..else搞懵逼了】),另外寫出來的代碼本身拓展性也會比較好。

      那么我們來看看策略模式,并且基于小貓遇到的場景問題,咱們來擼一下實現代碼。

      策略模式解決多路支付通道問題

      在定義支付行為的時候,我們首先定義出常規的支付行為,咱們可以用接口interface的形式定義出來,當然也可以用abstract類的方式定義出來。這里老貓使用后者來定義。代碼如下:

      /**
       * @author 公眾號:程序員老貓
       */
      public abstract class Payment {
          //獲取支付渠道的名稱
          public abstract String getName();
      
          //查詢用戶余額
          protected abstract BigDecimal queryBalance(String uid);
      
          public PayState doPay(String uid, BigDecimal amount) {
              if (queryBalance(uid).compareTo(amount) < 0) {
                  return new PayState(500, "支付失敗", "賬戶余額不足");
              }
              return new PayState(200, "支付成功", "支付金額:" + amount);
          }
      }
      

      定義一個標準的支付狀態類:

      /**
       * @author 公眾號:程序員老貓
       */
      public class PayState {
          private int code;
          private String msg;
          private Object data;
      
          public PayState(int code, String msg, Object data) {
              this.code = code;
              this.msg = msg;
              this.data = data;
          }
      
          public String toString() {
              return ("pay state :[" + code + "]," + msg + ",order detail: " + data);
          }
      }
      

      接下來,咱們來模擬各個支付渠道,并且咱們能夠知道在不同的支付渠道中,我們當前的賬戶余額是多少。咱們就拿用的比較多的微信、支付寶、京東支付等支付渠道來做模擬吧。

      支付寶實現,并且賬戶中有900元:

      public class AliPay extends Payment {
          @Override
          public String getName() {
              return "支付寶";
          }
      
          @Override
          protected BigDecimal queryBalance(String uid) {
              return new BigDecimal(900);
          }
      }
      

      微信支付,并且賬戶中有300元:

      public class WxPay extends Payment{
          @Override
          public String getName() {
              return "微信";
          }
      
          @Override
          protected BigDecimal queryBalance(String uid) {
              return new BigDecimal(300);
          }
      }
      

      以此類推,京東支付。

      public class JDPay extends Payment{
          @Override
          public String getName() {
              return "京東白條";
          }
      
          @Override
          protected BigDecimal queryBalance(String uid) {
              return new BigDecimal(400);
          }
      }
      

      定義好各種單一支付通道之后,其實我們就要組裝策略了。把上述支付通道,加載到策略路由類中。老貓覺得這個地方也是策略模式中比較核心的點。

      /**
       * @author 公眾號:程序員老貓
       */
      public class PayStrategy {
          public static final String ALI_PAY = "aliPay";
          public static final String WX_PAY = "wxPay";
          public static final String JD_PAY = "jdPay";
          public static final String DEFAULT = "wxPay";
      
          //初始化的時候裝載支付行為策略
          private static Map<String,Payment> paymentMap = new HashMap<>();
      
          static {
              paymentMap.put(ALI_PAY,new AliPay());
              paymentMap.put(WX_PAY,new WxPay());
              paymentMap.put(JD_PAY,new JDPay());
              paymentMap.put(DEFAULT,new WxPay());
          }
      
          //調用的時候路由具體的支付策略
          public static Payment get(String payKey){
              if(!paymentMap.containsKey(payKey)){
                  return paymentMap.get(DEFAULT);
              }
              return paymentMap.get(payKey);
          }
      }
      

      接下來,我們就模擬用戶下訂單支付行為了,具體如下:

      /**
       * @author 程序員老貓
       * 下單場景
       */
      public class Order {
          private String uid; //用戶Id
          private String orderId; //訂單Id
          private BigDecimal orderAmount; //支付金額
      
          public Order(String uid, String orderId, BigDecimal orderAmount) {
              this.uid = uid;
              this.orderId = orderId;
              this.orderAmount = orderAmount;
          }
      
          public PayState doPay() {
              return doPay(PayStrategy.DEFAULT);
          }
      
          public PayState doPay(String payKey) {
              Payment payment = PayStrategy.get(payKey);
              System.out.println("歡迎使用" + payment.getName());
              System.out.println("本次交易金額:" + orderAmount);
              return payment.doPay(uid, orderAmount);
          }
      }
      

      最終咱們來進行測試一下:

      public class PayStrategyTest {
          public static void main(String[] args) {
              Order order = new Order("ktdaddy","20240425224901",new BigDecimal(245));
      
              System.out.println(order.doPay(PayStrategy.ALI_PAY));
          }
      }
      

      結果輸出:

      歡迎使用支付寶
      本次交易金額:245
      pay state :[200],支付成功,order detail: 支付金額:245
      

      上述基本就是策略模式的使用了。老貓覺得應該還是比較清晰的。咱們簡單看一下最終的調用類圖:

      策略模式類圖

      到這里很多小伙伴可能會問了,上面寫的案例其實并沒有結合我們實際的spring開發框架去實現策略模式,日常開發的過程中我們Java程序員主要用的還是spring框架。那么如果要結合咱們spring日常開發框架又是怎么去實現呢。那么接下來,咱們接著往下看。

      SpringBoot下策略模式解決多路支付通道

      其實核心的思想還是上面這幾個要領,老貓在此不多做展開,只是給大家提供一些思路,然后提供一些簡單的日常開發中使用的截圖給大家參考。支付使用策略模式的核心的思想無非就下面兩個。

      (1)咱們需要不同的支付策略類。

      (2)需要有路由支付策略類的路由類。

      其實上面兩個核心中,比較重要的還是第二點,咱們如果去初始化策略類。在上面案例中,老貓使用的靜態方法塊來裝載各個策略方法。在spring中其實我們可以使用@PostConstruct注解,進行service策略的初始化裝載。

      如下首先定義一個標準的支付接口,并且實現一下:

      public interface Payment {
          //獲取支付渠道的名稱
          String getCode();
      
          PayState doPay(String uid, BigDecimal amount);
      }
      

      然后實現這個接口,咱們舉一個例子來說明

      @Service
      public class JDPay implements Payment {
      
          @Override
          public String getCode() {
              return "jdPay";
          }
      
          @Override
          public PayState doPay(String uid, BigDecimal amount) {
              return null;
          }
      }
      

      關鍵此時咱們看一下核心加載的地方。

      /**
       * 程序員老貓
       **/
      @Service
      public class PayStrategy {
          @Autowired
          private Payment[] payments;
      
          //初始化的時候裝載支付行為策略
          private static Map<String, Payment> paymentMap = new ConcurrentHashMap<>();
      
      
          @PostConstruct
          private void initRouteMap() {
              for (Payment externalPayService : payments) {
                  paymentMap.put(externalPayService.getCode(), externalPayService);
              }
          }
      
          public Payment getPayment(String payCode) {
              return paymentMap.get(payCode);
          }
      }
      

      上述就是結合spring的核心策略模式的實現方式,老貓這里沒有展開,但是最精華的部分,老貓覺得已經說清楚了。當然基于@PostConstruct進行策略加載的方式只是一種。大家可以實現spring自帶的InitializingBean,在 Spring 容器完成 bean 的屬性注入后,會調用 afterPropertiesSet() 方法來執行初始化邏輯。

      總結

      上述主要和大家分享了基于策略模式如何去做支付整合第三方支付的問題。當然這只是一個簡單的案例,其實很多時候我們在實際的業務開發中很多地方都可以用到這樣一個模式。在jdk源碼中以及spring源碼中也屢見不鮮。但是策略模式也不是萬能的,存在優點的同時也存在缺點。

      優點:

      1、策略模式符合開閉原則。(當然有興趣了解設計原則的小伙伴歡迎戳【違反這些設計原則,系統就等著“腐爛”】)

      2、策略模式可以避免使用多重復的條件語句。例如優化if else。當然之前也老貓也寫過類似博文。【接手了個項目,被if..else搞懵逼了

      3、使用策略模式可以提高算法的保密性和安全性。

      缺點:

      1、不像適配器模式,策略模式要求客戶端需要知道所有的策略,并且自行決定使用哪類策略。關于適配器模式,感興趣的小伙伴可以看這里【真香定律!我用這種模式重構了第三方登錄

      2、策略類會越來越多,維護成本也會越來越高。

      posted @ 2024-04-26 09:30  程序員老貓  閱讀(1237)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 男女性高爱潮免费网站| 国产亚洲av日韩精品熟女| 国产真实younv在线| 中文文字幕文字幕亚洲色| 日本一区二区三区四区黄色| 国产一区二区三区禁18| 国产精品视频白浆免费视频| 无码熟妇人妻AV在线影片最多| 377p欧洲日本亚洲大胆| 国产一级二级三级毛片| 国产亚洲一级特黄大片在线| 日本不卡三区| 国产va免费精品观看精品| 亚洲av成人区国产精品| 国产精品原创不卡在线| 日本欧美大码a在线观看| 色综合天天色综合久久网| 成人AV无码一区二区三区 | 安多县| 精品一卡2卡三卡4卡乱码精品视频| 亚洲美免无码中文字幕在线| 四虎av永久在线精品免费观看| 免费无码久久成人网站入口| 无码AV无码免费一区二区| 欧美成人精精品一区二区三区| 久久亚洲国产精品五月天| 久久亚洲色WWW成人男男| 亚洲人成网站18禁止无码| 人妻中文字幕精品系列| 免费无码AV一区二区波多野结衣| 国产婷婷综合在线视频| 撩起胸让我的?蹭来蹭去| 中文午夜乱理片无码| 欲香欲色天天天综合和网| 在线播放国产精品三级网| 亚洲欧美日韩综合久久久| 亚洲熟妇av一区二区三区宅男| 国产一区二区三区的视频| 精品国产精品中文字幕| 日本高清无卡码一区二区久久| 国产精品中文字幕第一区|