亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring Boot策略模式怎么使用

發布時間:2021-12-18 11:21:31 來源:億速云 閱讀:304 作者:iii 欄目:互聯網科技

這篇文章主要介紹“Spring Boot策略模式怎么使用”,在日常操作中,相信很多人在Spring Boot策略模式怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Spring Boot策略模式怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

未使用策略模式時的處理

以物聯網為例大家可能不夠熟悉,下面就以支付場景為例。比如在支付的過程中我們可能會選擇微信支付、支付寶支付或銀卡支付。同時,銀行卡又分不同銀行,這里統一為銀行卡。

最簡單直接的代碼實現形式如下:

public void pay(String payType){
    if("alipay".equals(payType)){
        System.out.println("支付寶");
    }else if("wechatPay".equals(payType)){
        System.out.println("微信支付");
    } else if("bank".equals(payType)){
        System.out.println("銀行卡支付");
    }
}

這樣對照設計模式,通常不符合兩個原則:單一職責原則和開閉原則。

我們會發現當前類(或方法)不處理了多個業務的功能,一旦任何一個支付方式的修改都可能會影響到其他的支付方式。同時,無法做到對擴展開放,對修改關閉。新增其他支付方式時同樣要修改ifelse判斷,影響到其他的業務邏輯。

而策略模式通常就是解決這種有很多ifelse處理邏輯,從而提高代碼的可維護性、可擴展性和可讀性。

策略模式的輪廓

在對上述代碼進行改造之前,先來了解一下策略模式的基本組成。

策略模式(Strategy),定義了一組算法,將每個算法都封裝起來,并且使它們之間可以互換。

策略模式通常有以下幾部分組成:

  • Strategy策略類,用于定義所有支持算法的公共接口;

  • ConcreteStrategy具體策略類,封裝了具體的算法或行為,繼承于Strategy。

  • Context上下文,用一個ConcreteStrategy來配置,維護一個對Strategy對象的引用;

  • StrategyFactory策略工廠類,用于創建策略類的具體實現;通常此部分可省略,看具體情況。比如后續實例中通過Spring的依賴注入機制實現了策略類的實例化。

用類圖來表示(省略策略工廠類)如下圖:

Spring Boot策略模式怎么使用

基于Spring的策略模式實現

目前在實踐中通常都是基于Spring的特性來實現策略模式,這里就以此為例來進行講解。

策略類定義

上面已經提到,策略類用于定義功能的接口,對于支付場景則可命名為PaymentService或PaymentStrategy。

public interface PaymentService {

    /**
     * 支付
     */
    PayResult pay(Order order);
}

同時提供該策略類的不同實現類:AlipayService、WeChatPayService、BankPayService。

@Service("alipay")
public class AlipayService implements PaymentService {
    @Override
    public PayResult pay(Order order) {
        System.out.println("Alipay");
        return null;
    }
}
@Service("wechatPay")
public class WeChatPayService implements PaymentService {
    @Override
    public PayResult pay(Order order) {
        System.out.println("WeChatPay");
        return null;
    }
}
@Service("bank")
public class BankPayService implements PaymentService {
    @Override
    public PayResult pay(Order order) {
        System.out.println("BankPay");
        return null;
    }
}

具體實現的實例化,可以通過一個PaymentFactory來進行構建存儲,也可以直接利用@Autowired形式注入到Context的List或Map當中。

PaymentFactory的實現如下:

public class PaymentFactory {

    private static final Map<String, PaymentService> payStrategies = new HashMap<>();

    static {
        payStrategies.put("alipay", new AlipayService());
        payStrategies.put("wechatPay", new WeChatPayService());
        payStrategies.put("bank", new BankPayService());
    }

    public static PaymentService getPayment(String payType) {
        if (payType == null) {
            throw new IllegalArgumentException("pay type is empty.");
        }
        if (!payStrategies.containsKey(payType)) {
            throw new IllegalArgumentException("pay type not supported.");
        }
        return payStrategies.get(payType);
    }
}

通過static靜態代碼塊來初始化對應的策略實現類,然后提供一個getPayment方法,根據支付類型來獲取對應的服務。當然,通過static初始化的代碼塊是單例的無狀態的,如果需要有狀態的類則getPayment方法,每次都需要new一個新的對象。

public static PaymentService getPayment1(String payType) {
    if (payType == null) {
        throw new IllegalArgumentException("pay type is empty.");
    }
    if ("alipay".equals(payType)) {
        return new AlipayService();
    } else if ("wechatPay".equals(payType)) {
        return new WeChatPayService();
    } else if ("bank".equals(payType)) {
        return new BankPayService();
    }
    throw new IllegalArgumentException("pay type not supported.");
}
Context上下文

Context上下文角色,也叫Context封裝角色,起承上啟下的作用,屏蔽高層模塊對策略、算法的直接訪問,封裝可能存在的變化。

上面通過工廠的形式創建策略類的實現類,當然也可以直接通過@Autowired注入到Context上下文中。

@Component
public class PaymentStrategy {

    @Autowired
    private final Map<String, PaymentService> payStrategies = new HashMap<>();

    public PaymentService getPayment(String payType) {
        if (payType == null) {
            throw new IllegalArgumentException("pay type is empty.");
        }
        if (!payStrategies.containsKey(payType)) {
            throw new IllegalArgumentException("pay type not supported.");
        }
        return payStrategies.get(payType);
    }
}

上面通過@Autowired注解,將通過@Service實例化的PaymentService實現類,注入到map當中,其中key為實例化類的名稱,value為具體的實例化類。

上面的getPayment代碼與PaymentFactory中一致。當然,還可以在PaymentStrategy中封裝一個pay方法,這樣,客戶端直接注入PaymentStrategy類調用pay方法即可。

public PayResult pay(String payType,Order order){
    PaymentService paymentService = this.getPayment(payType);
    return paymentService.pay(order);
}

改進方案

通過上面的代碼基本上已經實現了策略模式,此時當新增加一個支付通道時,已經不用修改PaymentStrategy相關的代碼,只用新增一個實現PaymentService接口的類即可。

但在接口定義這里,還是有優化空間的。比如,這里判斷是通過Bean的名稱來判斷的,但某些情況下判斷可能比較復雜或可能會同時執行多個Service。此時,就可以對PaymentService接口進行改進,新增一個檢驗是否支持該功能的判斷方法。

public interface PaymentService {

    boolean isSupport(Order order);

    /**
     * 支付
     */
    PayResult pay(Order order);
}

由實現類來具體實現isSupport方法,判斷自己支持哪些功能。

同時,上下文類也可以進一步利用Java8提供的Steam特性進行處理:

@Component
public class PaymentStrategy {

    /**
     * 此處用@Autowired將所有實例注入為List。
     */
    @Autowired
    private List<PaymentService> paymentServices;

    public void pay(Order order) {
        PaymentService paymentService = paymentServices.stream()
                .filter((service) -> service.isSupport(order))
                .findFirst()
                .orElse(null);

        if (paymentService != null) {
            paymentService.pay(order);
        } else {
            throw new IllegalArgumentException("pay type not supported.");
        }
    }
}

通過進一步改造,程序變得更加靈活了。

到此,關于“Spring Boot策略模式怎么使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

右玉县| 岢岚县| 会同县| 鱼台县| 巧家县| 全南县| 汾西县| 绥阳县| 隆尧县| 湛江市| 区。| 聊城市| 双柏县| 南汇区| 汕头市| 志丹县| 墨竹工卡县| 清苑县| 浦城县| 确山县| 汕尾市| 吉水县| 长兴县| 丰宁| 卓尼县| 石首市| 伊金霍洛旗| 胶州市| 丰县| 元阳县| 惠州市| 长治县| 中宁县| 沭阳县| 南澳县| 宁晋县| 平阴县| 乃东县| 卢湾区| 舞阳县| 大足县|