首頁/ 汽車/ 正文

Spring boot 運用策略模式實現,避免多次使用if

前言

這裡就不詳細去介紹策略模式是怎麼樣的了,想了解的可以點選下面的連結

策略模式介紹的連結:策略模式的介紹

這裡列出策略模式的好處

場景:某網頁有個支付,其中包含了微信、支付寶等方式的支付方式 ,後續明確還會進行相容其他的支付方式

用策略模式的好處:

避免多次使用if判斷具體是用哪種支付策略進行操作。

因為每種策略(微信支付、支付寶支付)的內容都比較複雜。策略模式能將每種策略分離出來,方面後續維護管理

下面我們將使用Spring boot 運用策略模式,實現上面的需求

環境配置

JDK8

Spring boot 2。3。7。RELEASE

整合了spring-boot-starter-web

實現目標

使用策略模式後,新加一種支付策略時,只需要在策略列舉中新增新加的策略資訊,外加一個策略類即可,而不再需要新增新的if判斷。

準備策略介面和具體實現策略類

支付策略介面

/** * 支付策略 */public interface PayStrategy { /** * 支付(引數就沒具體寫了,可以定義成每個支付必須要有的引數) * @return */ boolean pay();}複製程式碼

微信支付策略類

/** * 第三方——微信支付(這裡注意我修改了Bean的預設命名) */@Component(“wechatPayStrategy”)public class WeChatPayStrategyImpl implements PayStrategy{ /** * 支付 * @return */ @Override public boolean pay() { //進行微信的支付邏輯 System。out。println(“正在進行微信的支付邏輯”); return true; }}複製程式碼

支付寶支付策略類

/** * 支付寶第三方支付(這裡注意我修改了Bean的預設命名) */@Component(“alipayStrategy”)public class AliPayStrategyImpl implements PayStrategy { /** * 支付寶支付 * @return */ @Override public boolean pay() { //進行支付寶支付邏輯 System。out。println(“進行支付寶支付邏輯”); return true; }}複製程式碼

上述已將各自的策略的處理類進行了分離,接下來時使用支付策略工廠類和支付策略上下文將各自的策略類聯絡起來

準備支付策略上下文Context和支付策略工廠類

支付策略工廠類

package com。example。springboot_strategy。strategy。factory;import com。example。springboot_strategy。enums。PayStrategyEnum;import com。example。springboot_strategy。strategy。PayStrategy;import org。springframework。stereotype。Component;import javax。annotation。Resource;import javax。swing。plaf。synth。SynthTextAreaUI;import java。util。Map;/** * 支付策略工廠類 */@Componentpublic class PayStrategyFactory { /** * 透過Spring容器的方式注入 */ @Resource private Map payStrategyMap; /** * 獲取對應支付策略類 * @param payStrategyEnum 支付策略列舉 */ public PayStrategy getPayStrategy(PayStrategyEnum payStrategyEnum){ if(!payStrategyMap。containsKey(payStrategyEnum。getClassName())){ System。out。println(“沒有對應的支付策略,無法進行支付”); return null; } return payStrategyMap。get(payStrategyEnum。getClassName()); }}複製程式碼

這裡工廠類的邏輯是利用了Spring容器的處理方式,如果有

多種類同時實現了某個介面,那麼可以使用Map集合接收

,Map對應的泛型,String是Bean名稱,PayStrategy是每個具體實現類,這樣我們就可以使用Bean型別去指定具體的策略類了,然後建立一個支付策略列舉去管理這些Bean名稱。同時,也可以將Bean名稱與客戶端定義的型別進行關聯。

支付策略列舉類

/** * 支付策略型別 */public enum PayStrategyEnum { WECHAT_PAY(“wechat”,“wechatPayStrategy”,“微信支付”), ALIPAY(“alipay”,“alipayStrategy”,“支付寶支付”) ; /** * 支付策略code */ private String code; /** * bean名稱 */ private String className; /** * 資訊 */ private String info; PayStrategyEnum(String code,String className,String info){ this。code=code; this。className=className; this。info=info; } public String getCode() { return code; } public String getClassName() { return className; } public String getInfo() { return info; }}複製程式碼

上面列舉類中code代表的是客戶端定義的型別(例如我從前端接收到的支付type,這個type可以是這個code),className顧名思義,指的是每種策略的bean名稱,info是代表每種策略的內容

支付策略上下文

/** * 支付策略上下文 */@Componentpublic class PayStrategyContext { @Autowired private PayStrategyFactory payStrategyFactory; /** * 支付執行 * @param payDTO 支付引數 * @return */ public boolean payHandle(PayDTO payDTO){ //將某屬性的值轉換成具體的列舉。這裡是根據payDTO的type欄位對應列舉的code進行轉換 Optional payStrategyEnumOptional = Arrays。stream(PayStrategyEnum。class。getEnumConstants()) 。filter((e) -> e。getCode()。equals(payDTO。getType()))。findAny(); if(!payStrategyEnumOptional。isPresent()){ System。out。println(“匹配不到具體支付策略”); return false; } PayStrategyEnum payStrategyEnum = payStrategyEnumOptional。get(); PayStrategy payStrategy = payStrategyFactory。getPayStrategy(payStrategyEnum); //進行payDto引數的處理。。。。。 boolean pay = payStrategy。pay(); //支付後的記錄處理。。 return true; }}複製程式碼

pageDto類

/** * 支付DTO */public class PayDTO { /** * 支付型別 */ private String type; /** * 支付金額 */ private BigDecimal payMoney; /** * ……。。。。。 */ public String getType() { return type; } public void setType(String type) { this。type = type; } public BigDecimal getPayMoney() { return payMoney; } public void setPayMoney(BigDecimal payMoney) { this。payMoney = payMoney; }}複製程式碼

這個策略上下文,則是選擇策略的入口,這裡會進行引數的處理,將這裡我就將pageDTO類中的type字串轉換成對應的列舉類。

到這裡使用策略模式的編寫算是完成了,下面進行編寫客戶端的程式碼

客戶端程式碼

支付控制器

@RestController@RequestMapping(“pay”)public class PayController { @Autowired private PayStrategyContext payStrategyContext; @PostMapping public boolean pay(@RequestBody PayDTO payDTO){ //這裡因為懶。。就沒有加上Service層了,直接在控制器處理 return payStrategyContext。payHandle(payDTO); }}複製程式碼

效果

Spring boot 運用策略模式實現,避免多次使用if

新需求

後續新增一個銀聯的支付方式,我們只需要

新增銀聯的支付策略類和新增銀聯的支付列舉即可實現

新增銀聯的支付策略類

/** * 銀聯支付(這裡注意我修改了Bean的預設命名) */@Component(“unionPayStrategy”)public class UnionPayStrategyImp implements PayStrategy { /** * 銀聯支付 * @return */ @Override public boolean pay() { //進行銀聯的支付 System。out。println(“進行銀聯的支付邏輯”); return true; }}複製程式碼

在列舉類中新增銀聯的支付列舉

/** * 支付策略型別 */public enum PayStrategyEnum { WECHAT_PAY(“wechat”,“wechatPayStrategy”,“微信支付”), ALIPAY(“alipay”,“alipayStrategy”,“支付寶支付”), UNION_PAY(“unionpay”,“unionPayStrategy”,“銀聯支付”) ; /** * 支付策略code */ private String code; /** * bean名稱 */ private String className; /** * 資訊 */ private String info; PayStrategyEnum(String code,String className,String info){ this。code=code; this。className=className; this。info=info; } public String getCode() { return code; } public String getClassName() { return className; } public String getInfo() { return info; }}複製程式碼

實現效果

Spring boot 運用策略模式實現,避免多次使用if

以上是我使用Spring boot 運用策略模式實現的效果,如果有誤人子弟的地方,望在評論區指出。

相關文章

頂部