Spring?boot?運用策略模式實現(xiàn)避免多次使用if
前言
這里就不詳細去介紹策略模式是怎么樣的了,想了解的可以點擊下面的鏈接
策略模式介紹的鏈接:Java 設計模式中的策略模式詳情
這里列出策略模式的好處
場景:某網頁有個支付,其中包含了微信、支付寶等方式的支付方式 ,后續(xù)明確還會進行兼容其他的支付方式
用策略模式的好處:
- 避免多次使用if判斷具體是用哪種支付策略進行操作。
- 因為每種策略(微信支付、支付寶支付)的內容都比較復雜。策略模式能將每種策略分離出來,方面后續(xù)維護管理
下面我們將使用Spring boot 運用策略模式,實現(xiàn)上面的需求
環(huán)境配置
- JDK8
- Spring boot 2.3.7.RELEASE
- 整合了spring-boot-starter-web
實現(xiàn)目標
使用策略模式后,新加一種支付策略時,只需要在策略枚舉中添加新加的策略信息,外加一個策略類即可,而不再需要添加新的if判斷。
準備策略接口和具體實現(xiàn)策略類
支付策略接口
/**
* 支付策略
*/
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;
}
}上述已將各自的策略的處理類進行了分離,接下來時使用支付策略工廠類和支付策略上下文將各自的策略類聯(lián)系起來
準備支付策略上下文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;
/**
* 支付策略工廠類
*/
@Component
public class PayStrategyFactory {
/**
* 通過Spring容器的方式注入
*/
@Resource
private Map<String, PayStrategy> payStrategyMap;
/**
* 獲取對應支付策略類
* @param payStrategyEnum 支付策略枚舉
*/
public PayStrategy getPayStrategy(PayStrategyEnum payStrategyEnum){
if(!payStrategyMap.containsKey(payStrategyEnum.getClassName())){
System.out.println("沒有對應的支付策略,無法進行支付");
return null;
}
return payStrategyMap.get(payStrategyEnum.getClassName());
}
}這里工廠類的邏輯是利用了Spring容器的處理方式,如果有多種類同時實現(xiàn)了某個接口,那么可以使用Map集合接收,Map對應的泛型,String是Bean名稱,PayStrategy是每個具體實現(xiàn)類,這樣我們就可以使用Bean類型去指定具體的策略類了,然后建立一個支付策略枚舉去管理這些Bean名稱。同時,也可以將Bean名稱與客戶端定義的類型進行關聯(lián)。
支付策略枚舉類
/**
* 支付策略類型
*/
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是代表每種策略的內容
支付策略上下文
/**
* 支付策略上下文
*/
@Component
public class PayStrategyContext {
@Autowired
private PayStrategyFactory payStrategyFactory;
/**
* 支付執(zhí)行
* @param payDTO 支付參數
* @return
*/
public boolean payHandle(PayDTO payDTO){
//將某屬性的值轉換成具體的枚舉。這里是根據payDTO的type字段對應枚舉的code進行轉換
Optional<PayStrategyEnum> 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);
}
}效果

新需求
后續(xù)新增一個銀聯(lián)的支付方式,我們只需要添加銀聯(lián)的支付策略類和添加銀聯(lián)的支付枚舉即可實現(xiàn)
添加銀聯(lián)的支付策略類
/**
* 銀聯(lián)支付(這里注意我修改了Bean的默認命名)
*/
@Component("unionPayStrategy")
public class UnionPayStrategyImp implements PayStrategy {
/**
* 銀聯(lián)支付
* @return
*/
@Override
public boolean pay() {
//進行銀聯(lián)的支付
System.out.println("進行銀聯(lián)的支付邏輯");
return true;
}
}在枚舉類中添加銀聯(lián)的支付枚舉
/**
* 支付策略類型
*/
public enum PayStrategyEnum {
WECHAT_PAY("wechat","wechatPayStrategy","微信支付"),
ALIPAY("alipay","alipayStrategy","支付寶支付"),
UNION_PAY("unionpay","unionPayStrategy","銀聯(lián)支付")
;
/**
* 支付策略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;
}
}
復制代碼實現(xiàn)效果

到此這篇關于Spring boot 運用策略模式實現(xiàn)避免多次使用if的文章就介紹到這了,更多相關Spring boot 避免多次使用if內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot整合Swagger3生成接口文檔過程解析
這篇文章主要介紹了SpringBoot整合Swagger3生成接口文檔過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-07-07
Spring創(chuàng)建Bean的過程Debug的詳細流程
這篇文章主要介紹了Spring創(chuàng)建Bean的過程Debug的流程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11
jvm中指定時區(qū)信息user.timezone問題及解決方式
同一份程序使用時間LocalDateTime類型,在國內和國外部署后,返回的時間信息前端使用出問題,這篇文章主要介紹了jvm中指定時區(qū)信息user.timezone問題及解決方法,需要的朋友可以參考下2023-02-02
詳解eclipse創(chuàng)建maven項目實現(xiàn)動態(tài)web工程完整示例
這篇文章主要介紹了詳解eclipse創(chuàng)建maven項目實現(xiàn)動態(tài)web工程完整示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12
Spring Boot+Shiro實現(xiàn)一個Http請求的Basic認證
本文向向大家仔細的介紹了如何使用Shiro實現(xiàn)一個Http請求的Basic認證,有此需求的朋友可以參考下本文2021-06-06
SpringCloud實戰(zhàn)之Feign聲明式服務調用
這篇文章主要介紹了SpringCloud實戰(zhàn)之Feign聲明式服務調用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-05-05

