成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

基于Spring(Boot)下策略模式的使用方法教程

這篇文章主要講解了“基于Spring(Boot)下策略模式的使用方法教程”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“基于Spring(Boot)下策略模式的使用方法教程”吧!

在新吳等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專(zhuān)注、極致的服務(wù)理念,為客戶(hù)提供成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作定制開(kāi)發(fā),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站設(shè)計(jì),成都全網(wǎng)營(yíng)銷(xiāo)推廣,成都外貿(mào)網(wǎng)站建設(shè)公司,新吳網(wǎng)站建設(shè)費(fèi)用合理。

未使用策略模式時(shí)的處理

以物聯(lián)網(wǎng)為例大家可能不夠熟悉,下面就以支付場(chǎng)景為例。比如在支付的過(guò)程中我們可能會(huì)選擇微信支付、支付寶支付或銀卡支付。同時(shí),銀行卡又分不同銀行,這里統(tǒng)一為銀行卡。

最簡(jiǎn)單直接的代碼實(shí)現(xiàn)形式如下:

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("銀行卡支付");     } }

這樣對(duì)照設(shè)計(jì)模式,通常不符合兩個(gè)原則:?jiǎn)我宦氊?zé)原則和開(kāi)閉原則。

我們會(huì)發(fā)現(xiàn)當(dāng)前類(lèi)(或方法)不處理了多個(gè)業(yè)務(wù)的功能,一旦任何一個(gè)支付方式的修改都可能會(huì)影響到其他的支付方式。同時(shí),無(wú)法做到對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。新增其他支付方式時(shí)同樣要修改ifelse判斷,影響到其他的業(yè)務(wù)邏輯。

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

策略模式的輪廓

在對(duì)上述代碼進(jìn)行改造之前,先來(lái)了解一下策略模式的基本組成。

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

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

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

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

  • Context上下文,用一個(gè)ConcreteStrategy來(lái)配置,維護(hù)一個(gè)對(duì)Strategy對(duì)象的引用;

  • StrategyFactory策略工廠類(lèi),用于創(chuàng)建策略類(lèi)的具體實(shí)現(xiàn);通常此部分可省略,看具體情況。比如后續(xù)實(shí)例中通過(guò)Spring的依賴(lài)注入機(jī)制實(shí)現(xiàn)了策略類(lèi)的實(shí)例化。

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

基于Spring(Boot)下策略模式的使用方法教程

image

基于Spring的策略模式實(shí)現(xiàn)

目前在實(shí)踐中通常都是基于Spring的特性來(lái)實(shí)現(xiàn)策略模式,這里就以此為例來(lái)進(jìn)行講解。

策略類(lèi)定義

上面已經(jīng)提到,策略類(lèi)用于定義功能的接口,對(duì)于支付場(chǎng)景則可命名為PaymentService或PaymentStrategy。

public interface PaymentService {      /**      * 支付      */     PayResult pay(Order order); }

同時(shí)提供該策略類(lèi)的不同實(shí)現(xiàn)類(lèi):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;     } }

具體實(shí)現(xiàn)的實(shí)例化,可以通過(guò)一個(gè)PaymentFactory來(lái)進(jìn)行構(gòu)建存儲(chǔ),也可以直接利用@Autowired形式注入到Context的List或Map當(dāng)中。

PaymentFactory的實(shí)現(xiàn)如下:

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

通過(guò)static靜態(tài)代碼塊來(lái)初始化對(duì)應(yīng)的策略實(shí)現(xiàn)類(lèi),然后提供一個(gè)getPayment方法,根據(jù)支付類(lèi)型來(lái)獲取對(duì)應(yīng)的服務(wù)。當(dāng)然,通過(guò)static初始化的代碼塊是單例的無(wú)狀態(tài)的,如果需要有狀態(tài)的類(lèi)則getPayment方法,每次都需要new一個(gè)新的對(duì)象。

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封裝角色,起承上啟下的作用,屏蔽高層模塊對(duì)策略、算法的直接訪問(wèn),封裝可能存在的變化。

上面通過(guò)工廠的形式創(chuàng)建策略類(lèi)的實(shí)現(xiàn)類(lèi),當(dāng)然也可以直接通過(guò)@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);     } }

上面通過(guò)@Autowired注解,將通過(guò)@Service實(shí)例化的PaymentService實(shí)現(xiàn)類(lèi),注入到map當(dāng)中,其中key為實(shí)例化類(lèi)的名稱(chēng),value為具體的實(shí)例化類(lèi)。

上面的getPayment代碼與PaymentFactory中一致。當(dāng)然,還可以在PaymentStrategy中封裝一個(gè)pay方法,這樣,客戶(hù)端直接注入PaymentStrategy類(lèi)調(diào)用pay方法即可。

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

改進(jìn)方案

通過(guò)上面的代碼基本上已經(jīng)實(shí)現(xiàn)了策略模式,此時(shí)當(dāng)新增加一個(gè)支付通道時(shí),已經(jīng)不用修改PaymentStrategy相關(guān)的代碼,只用新增一個(gè)實(shí)現(xiàn)PaymentService接口的類(lèi)即可。

但在接口定義這里,還是有優(yōu)化空間的。比如,這里判斷是通過(guò)Bean的名稱(chēng)來(lái)判斷的,但某些情況下判斷可能比較復(fù)雜或可能會(huì)同時(shí)執(zhí)行多個(gè)Service。此時(shí),就可以對(duì)PaymentService接口進(jìn)行改進(jìn),新增一個(gè)檢驗(yàn)是否支持該功能的判斷方法。

public interface PaymentService {      boolean isSupport(Order order);      /**      * 支付      */     PayResult pay(Order order); }

由實(shí)現(xiàn)類(lèi)來(lái)具體實(shí)現(xiàn)isSupport方法,判斷自己支持哪些功能。

同時(shí),上下文類(lèi)也可以進(jìn)一步利用Java8提供的Steam特性進(jìn)行處理:

@Component public class PaymentStrategy {      /**      * 此處用@Autowired將所有實(shí)例注入為L(zhǎng)ist。      */     @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.");         }     } }

通過(guò)進(jìn)一步改造,程序變得更加靈活了。

感謝各位的閱讀,以上就是“基于Spring(Boot)下策略模式的使用方法教程”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)基于Spring(Boot)下策略模式的使用方法教程這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

網(wǎng)站欄目:基于Spring(Boot)下策略模式的使用方法教程
標(biāo)題URL:http://jinyejixie.com/article28/iehjjp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁(yè)設(shè)計(jì)公司、標(biāo)簽優(yōu)化、外貿(mào)建站、微信公眾號(hào)響應(yīng)式網(wǎng)站、靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

微信小程序開(kāi)發(fā)
孟连| 武宣县| 乌海市| 临沂市| 澄迈县| 裕民县| 吉木萨尔县| 禹城市| 枞阳县| 杂多县| 读书| 眉山市| 郑州市| 苍南县| 志丹县| 浦城县| 英吉沙县| 来凤县| 丹凤县| 彰武县| 麻城市| 黄陵县| 长子县| 龙井市| 龙口市| 县级市| 郸城县| 广南县| 玉溪市| 乐业县| 偃师市| 霍邱县| 大港区| 屯门区| 富顺县| 中牟县| 云林县| 盐亭县| 安福县| 临西县| 浦县|