日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

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

來源: 責編: 時間:2024-04-26 17:36:06 184觀看
導讀老貓的設計模式專欄已經偷偷發車了。不甘愿做crud boy?看了好幾遍的設計模式還記不住?那就不要刻意記了,跟上老貓的步伐,在一個個有趣的職場故事中領悟設計模式的精髓吧。還等什么?趕緊上車吧。故事“不能再寫if else來拓

老貓的設計模式專欄已經偷偷發車了。不甘愿做crud boy?看了好幾遍的設計模式還記不住?那就不要刻意記了,跟上老貓的步伐,在一個個有趣的職場故事中領悟設計模式的精髓吧。還等什么?趕緊上車吧。LZe28資訊網——每日最新資訊28at.com

故事

“不能再寫if else來拓展當前系統了,現在已經有三個支付場景了......”工位上,小貓看著電腦,撓著頭。LZe28資訊網——每日最新資訊28at.com

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

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

深思熟慮很久,小貓下定決心打算用“策略模式”重構一番。LZe28資訊網——每日最新資訊28at.com

聊聊策略模式

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

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

(1)系統中有很多類,而它們的區別僅僅在于行為不同。LZe28資訊網——每日最新資訊28at.com

(2)一個系統需要動態地在幾種算法中選擇一種。LZe28資訊網——每日最新資訊28at.com

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

那么我們來看看策略模式,并且基于小貓遇到的場景問題,咱們來擼一下實現代碼。LZe28資訊網——每日最新資訊28at.com

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

在定義支付行為的時候,我們首先定義出常規的支付行為,咱們可以用接口interface的形式定義出來,當然也可以用abstract類的方式定義出來。這里老貓使用后者來定義。代碼如下:LZe28資訊網——每日最新資訊28at.com

/** * @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);    }}

定義一個標準的支付狀態類:LZe28資訊網——每日最新資訊28at.com

/** * @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);    }}

接下來,咱們來模擬各個支付渠道,并且咱們能夠知道在不同的支付渠道中,我們當前的賬戶余額是多少。咱們就拿用得比較多的微信、支付寶、京東支付等支付渠道來做模擬吧。LZe28資訊網——每日最新資訊28at.com

支付寶實現,并且賬戶中有900元:LZe28資訊網——每日最新資訊28at.com

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

微信支付,并且賬戶中有300元:LZe28資訊網——每日最新資訊28at.com

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

以此類推,京東支付。LZe28資訊網——每日最新資訊28at.com

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

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

/** * @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);    }}

接下來,我們就模擬用戶下訂單支付行為了,具體如下:LZe28資訊網——每日最新資訊28at.com

/** * @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);    }}

最終咱們來進行測試一下:LZe28資訊網——每日最新資訊28at.com

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));    }}

結果輸出:LZe28資訊網——每日最新資訊28at.com

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

上述基本就是策略模式的使用了。老貓覺得應該還是比較清晰的。咱們簡單看一下最終的調用類圖:LZe28資訊網——每日最新資訊28at.com

策略模式類圖策略模式類圖LZe28資訊網——每日最新資訊28at.com

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

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

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

(1)咱們需要不同的支付策略類。LZe28資訊網——每日最新資訊28at.com

(2)需要有路由支付策略類的路由類。LZe28資訊網——每日最新資訊28at.com

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

如下首先定義一個標準的支付接口,并且實現一下:LZe28資訊網——每日最新資訊28at.com

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

然后實現這個接口,咱們舉一個例子來說明LZe28資訊網——每日最新資訊28at.com

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

關鍵此時咱們看一下核心加載的地方。LZe28資訊網——每日最新資訊28at.com

/** * 程序員老貓 **/@Servicepublic 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() 方法來執行初始化邏輯。LZe28資訊網——每日最新資訊28at.com

總結

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

優點:LZe28資訊網——每日最新資訊28at.com

1、策略模式符合開閉原則。(當然有興趣了解設計原則的小伙伴歡迎戳【違反這些設計原則,系統就等著“腐爛”】)LZe28資訊網——每日最新資訊28at.com

2、策略模式可以避免使用多重復的條件語句。例如優化if else。之前老貓也寫過類似博文。【接手了個項目,被if..else搞懵逼了】LZe28資訊網——每日最新資訊28at.com

3、使用策略模式可以提高算法的保密性和安全性。LZe28資訊網——每日最新資訊28at.com

缺點:LZe28資訊網——每日最新資訊28at.com

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

2、策略類會越來越多,維護成本也會越來越高。LZe28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-85877-0.html不得不說,在很多業務中,這種模式用得真的很香

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: WPF開發:使用命令模式實現Undo和Redo功能

下一篇: 消息稱英偉達收購以色列高效 AI 模型企業 Deci,后者曾拿下 7B 量級模型第一

標簽:
  • 熱門焦點
  • Automa-通過連接塊來自動化你的瀏覽器

    1、前言通過瀏覽器插件可實現自動化腳本的錄制與編寫,具有代表性的工具就是:Selenium IDE、Katalon Recorder,對于簡單的業務來說可快速實現自動化的上手工作。Selenium IDEKat
  • 微信語音大揭秘:為什么禁止轉發?

    大家好,我是你們的小米。今天,我要和大家聊一個有趣的話題:為什么微信語音不可以轉發?這是一個我們經常在日常使用中遇到的問題,也是一個讓很多人好奇的問題。讓我們一起來揭開這
  • 三分鐘白話RocketMQ系列—— 如何發送消息

    我們知道RocketMQ主要分為消息 生產、存儲(消息堆積)、消費 三大塊領域。那接下來,我們白話一下,RocketMQ是如何發送消息的,揭秘消息生產全過程。注意,如果白話中不小心提到相關代
  • JVM優化:實戰OutOfMemoryError異常

    一、Java堆溢出堆內存中主要存放對象、數組等,只要不斷地創建這些對象,并且保證 GC Roots 到對象之間有可達路徑來避免垃 圾收集回收機制清除這些對象,當這些對象所占空間超過
  • “又被陳思誠騙了”

    作者|張思齊 出品|眾面(ID:ZhongMian_ZM)如今的國產懸疑電影,成了陳思誠的天下。最近大爆電影《消失的她》票房突破30億斷層奪魁暑期檔,陳思誠再度風頭無兩。你可以說陳思誠的
  • 阿里瓴羊One推出背后,零售企業迎數字化新解

    作者:劉曠近年來隨著數字經濟的高速發展,各式各樣的SaaS應用服務更是層出不窮,但本質上SaaS大多局限于單一業務流層面,對用戶核心關切的增長問題等則沒有提供更好的解法。在Saa
  • OPPO、vivo、小米等國內廠商Q2在印度智能手機市場份額依舊高達55%

    7月20日消息,據外媒報道,研究機構的報告顯示,在全球智能手機出貨量同比仍在下滑的大背景下,印度這一有潛力的市場也未能幸免,出貨量同比也有下滑,多家廠
  • 到手價3099元起!iQOO Neo8 Pro今日首銷:安卓性能最強旗艦

    5月23日,iQOO如期舉行了新品發布會,全新的iQOO Neo8系列也正式與大家見面,包含iQOO Neo8和iQOO Neo8 Pro兩個版本,其中標準版搭載高通驍龍8+,而Pro版更
  • 聯想YOGA 16s 2022筆記本將要推出,屏幕支持觸控功能

    聯想此前宣布,將于11月2日19:30召開聯想秋季輕薄新品發布會,推出聯想 YOGA 16s 2022 筆記本等新品。官方稱,YOGA 16s 2022 筆記本將搭載 16 英寸屏幕,并且是一
Top 主站蜘蛛池模板: 锡林郭勒盟| 彰武县| 永丰县| 保亭| 平度市| 洪湖市| 永兴县| 岳阳县| 临湘市| 汉川市| 襄樊市| 凤山市| 韶山市| 上犹县| 广灵县| 资兴市| 吉林省| 衡阳市| 通道| 阜阳市| 巴青县| 固镇县| 大关县| 大田县| 浏阳市| 武威市| 怀来县| 嘉祥县| 玛多县| 中超| 长治市| 马公市| 湟中县| 牙克石市| 繁峙县| 垣曲县| 华坪县| 富阳市| 文山县| 灵璧县| 弥渡县|