從聚合支付業務的設計來聊聊策略模式

六月福利

2020年6月公衆號碼農小胖哥原創文章轉發第一名將送全新《Spring Boot實戰》實體書一本,該書是學習熱門框架 Spring Boot的經典之做。你再也不須要依靠運氣,而是勤奮。截止統計日期2020年6月30日,統計數據以官方公衆號工具爲準,運營人員不參加活動,本次活動圖書由掘金社區贊助。html

1. 前言

前幾天講了設計模式中的命令模式,今天來看看另外一個模式。移動支付目前在國內已是很是普及了,連樓下早餐攤的七十多歲大媽也使用支付寶和微信支付賣雞蛋餅。若是讓你作一個App你確定要考慮多個渠道支付,以保證獲客渠道。若是讓你來接入多種支付渠道你會怎麼設計?java

2. 一般寫法

通常下面這種寫法很容易被創造出來:算法

public boolean pay(BigDecimal amount){
        
        boolean ret =false;
        if (alipay){
            //todo 支付寶的邏輯
        }else if (wechatpay){
            //todo 微信支付的邏輯
        }else if (ooxx){
           // …… 
        }
        return ret;
    }

若是集成了四五種支付,這個代碼就無法看了少說幾千行,並且改動某個支付的邏輯很容易改了其它支付的邏輯。所以須要合理的設計來避免這種風險。編程

3. 策略模式

大部分的支付能夠簡化爲這個流程:設計模式

中間的發起支付前邏輯支付後處理邏輯是客戶端的自定義業務邏輯,向支付服務器發送的請求只會攜帶對應支付服務器特定要求的參數調用不一樣的支付SDK。因此咱們分別創建對應支付方式的策略來隔離區分它們,下降它們的耦合度。當準備支付時咱們只須要選擇對應的策略就能夠了。服務器

這就用到了設計模式中的策略模式:微信

結合上面的類圖,咱們就來結合着需求來聊聊策略模式中的主要幾個角色。框架

  • Strategy接口。這個接口用來聲明每一種方式的獨立執行策略,用來封裝具體策略的特有算法邏輯。
  • ConcreteStrategyStrategy的實現類。實現了不一樣策略的算法邏輯。好比每種支付的調用細節等等。
  • Context上下文。它經過策略接口來引用了具體的策略並使用具體的策略來執行邏輯,同時全部策略的共性也能夠在該類中進行統一處理。在聚合支付需求中咱們傳入一個策略,先執行支付前的邏輯,而後使用策略,策略執行完畢後,再執行後置的共性邏輯。
  • Client客戶端。建立策略對象並傳遞給上下文Context,而後由上下文運行具體的策略。

結合業務邏輯是這樣的:請求到達客戶端,客戶端根據請求中包含的支付渠道來構建對應的策略對象並把它交給上下文對象去執行支付流程。函數式編程

而後咱們就能夠分別爲支付寶、微信支付、銀聯支付構造三個策略對象 AliPayStrategyWechatPayStrategyUnionPayStrategy ,咱們來模擬一下執行策略:函數

public class Client {

    public static void main(String[] args) {
        // 獲取請求中的支付渠道標識
        String code = "p01";
        PayStrategy payStrategy = null;
        PayRequest request = null;
        
        if (PayType.ALI.getCode().equals(code)) {
            //組裝爲支付寶支付策略
            payStrategy = new AliPayStrategy();
            // 構造支付寶請求參數
            request = new AliPayRequest();
        }
        if (PayType.WECHAT.getCode().equals(code)) {
            //組裝爲微信支付策略
            payStrategy = new AliPayStrategy();
            // 構造微信支付請求參數
            request = new WechatPayRequest();
        }

        if (PayType.UNION.getCode().equals(code)) {
            //組裝爲銀聯支付策略
            payStrategy = new UnionPayStrategy();
            // 構造銀聯支付請求參數
            request = new UnionPayRequest();
        }

        if (Objects.nonNull(payStrategy)) {
            PayContext payContext = new PayContext();
            payContext.setPayStrategy(payStrategy);
            payContext.pay(request);
        }
    }
}

咱們拿到請求中的支付標識,而後初始化對應的支付策略,封裝指定的請求參數,交給上下文對象PayContext 來執行請求。若是你再增長什麼ApplePay之類的去實現ApplePayStrategy就好了。

4. 優缺點

策略模式並不都帶來正面的做用。

4.1 優勢

  • 咱們將算法的實現和算法的使用進行了隔離,算法實現只關心算法邏輯,使用算法只關心什麼條件下使用什麼算法。
  • 開閉原則,無需修改上下文對象,想擴展只須要引入新的策略。
  • 運行時根據條件動態的去切換算法。
  • 適應個性的同時也能夠兼容共性。

4.2 缺點

  • 客戶端必須明確知道激活策略的條件。
  • 引入太多的策略類。
  • 可被一些函數式接口所代替。僞代碼Pay.request(data).strategy(data->{ })

5. 總結

策略模式也是很常見並且有着普遍使用場景的設計模式。今天咱們從聚合支付來學習了策略模式,對它的優缺點也進行了一個分析。隨着函數式編程的普及,策略模式開始被逐漸的代替,可是它依然值得咱們去學習。感謝你的閱讀,多多關注:碼農小胖哥,更多編程乾貨奉上。

關注公衆號:Felordcn 獲取更多資訊

我的博客:https://felord.cn

相關文章
相關標籤/搜索