精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

再一次實戰策略模式,真是太好用了

開發 前端
之前做三方支付系統的時候經常用到策略模式,比如用戶會選擇不同的支付方式,不同的支付方式又有不同的實現方法或銀行接口調用。

[[384718]]

本文轉載自微信公眾號「程序新視界」,作者二師兄。轉載本文請聯系程序新視界公眾號。   

前言

之前做三方支付系統的時候經常用到策略模式,比如用戶會選擇不同的支付方式,不同的支付方式又有不同的實現方法或銀行接口調用。

現在做物聯網系統,基于MQTT協議(TCP層面的協議)來傳輸數據,根據不同的請求(不同的Topic)處理不同的業務邏輯,也同樣用到策略模式。

頓時感覺策略模式非常好用,而且結合Spring的實例化和注入功能,更加方便了。

今天就聊聊基于Spring(Boot)下策略模式的使用。

未使用策略模式時的處理

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

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

  1. public void pay(String payType){ 
  2.     if("alipay".equals(payType)){ 
  3.         System.out.println("支付寶"); 
  4.     }else if("wechatPay".equals(payType)){ 
  5.         System.out.println("微信支付"); 
  6.     } else if("bank".equals(payType)){ 
  7.         System.out.println("銀行卡支付"); 
  8.     } 

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

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

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

策略模式的輪廓

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

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

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

  • Strategy策略類,用于定義所有支持算法的公共接口;
  • ConcreteStrategy具體策略類,封裝了具體的算法或行為,繼承于Strategy。
  • Context上下文,用一個ConcreteStrategy來配置,維護一個對Strategy對象的引用;
  • StrategyFactory策略工廠類,用于創建策略類的具體實現;通常此部分可省略,看具體情況。比如后續實例中通過Spring的依賴注入機制實現了策略類的實例化。

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

image

 

基于Spring的策略模式實現

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

策略類定義

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

  1. public interface PaymentService { 
  2.  
  3.     /** 
  4.      * 支付 
  5.      */ 
  6.     PayResult pay(Order order); 

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

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

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

PaymentFactory的實現如下:

  1. public class PaymentFactory { 
  2.  
  3.     private static final Map<String, PaymentService> payStrategies = new HashMap<>(); 
  4.  
  5.     static { 
  6.         payStrategies.put("alipay", new AlipayService()); 
  7.         payStrategies.put("wechatPay", new WeChatPayService()); 
  8.         payStrategies.put("bank", new BankPayService()); 
  9.     } 
  10.  
  11.     public static PaymentService getPayment(String payType) { 
  12.         if (payType == null) { 
  13.             throw new IllegalArgumentException("pay type is empty."); 
  14.         } 
  15.         if (!payStrategies.containsKey(payType)) { 
  16.             throw new IllegalArgumentException("pay type not supported."); 
  17.         } 
  18.         return payStrategies.get(payType); 
  19.     } 

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

  1. public static PaymentService getPayment1(String payType) { 
  2.     if (payType == null) { 
  3.         throw new IllegalArgumentException("pay type is empty."); 
  4.     } 
  5.     if ("alipay".equals(payType)) { 
  6.         return new AlipayService(); 
  7.     } else if ("wechatPay".equals(payType)) { 
  8.         return new WeChatPayService(); 
  9.     } else if ("bank".equals(payType)) { 
  10.         return new BankPayService(); 
  11.     } 
  12.     throw new IllegalArgumentException("pay type not supported."); 

Context上下文

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

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

  1. @Component 
  2. public class PaymentStrategy { 
  3.  
  4.     @Autowired 
  5.     private final Map<String, PaymentService> payStrategies = new HashMap<>(); 
  6.  
  7.     public PaymentService getPayment(String payType) { 
  8.         if (payType == null) { 
  9.             throw new IllegalArgumentException("pay type is empty."); 
  10.         } 
  11.         if (!payStrategies.containsKey(payType)) { 
  12.             throw new IllegalArgumentException("pay type not supported."); 
  13.         } 
  14.         return payStrategies.get(payType); 
  15.     } 

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

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

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

改進方案

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

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

  1. public interface PaymentService { 
  2.  
  3.     boolean isSupport(Order order); 
  4.  
  5.     /** 
  6.      * 支付 
  7.      */ 
  8.     PayResult pay(Order order); 

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

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

  1. @Component 
  2. public class PaymentStrategy { 
  3.  
  4.     /** 
  5.      * 此處用@Autowired將所有實例注入為List。 
  6.      */ 
  7.     @Autowired 
  8.     private List<PaymentService> paymentServices; 
  9.  
  10.     public void pay(Order order) { 
  11.         PaymentService paymentService = paymentServices.stream() 
  12.                 .filter((service) -> service.isSupport(order)) 
  13.                 .findFirst() 
  14.                 .orElse(null); 
  15.  
  16.         if (paymentService != null) { 
  17.             paymentService.pay(order); 
  18.         } else { 
  19.             throw new IllegalArgumentException("pay type not supported."); 
  20.         } 
  21.     } 

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

小結

通過上面的代碼實現,可以看出接口類只負責業務策略的定義,策略的具體實現可以單獨放在實現類中也可以利用Spring的特性進行管理,Context上下文類負責業務邏輯的編排。

通過策略模式(或變種)的應用,實現了面向接口而非實現編程,滿足了職責單一、開閉原則,從而達到了功能上的高內聚低耦合、提高了可維護性、擴展性以及代碼的可讀性。

 

最后,對于設計模式,只有在實踐中不斷的使用采用更加印象深刻。同時,在實現的過程中我們也并不一定非要拘泥于設計模式本身,也可以結合所使用的框架進行變種處理。

 

責任編輯:武曉燕 來源: 程序新視界
相關推薦

2016-03-17 13:50:17

融合通信華為

2012-03-09 15:55:05

新版

2017-02-28 11:13:36

華為

2015-08-07 13:36:49

南京軟博會

2013-08-23 10:12:02

蘋果iPhone 5S

2015-05-28 09:58:00

手機電池續航內存

2015-10-14 13:02:37

ios9越獄

2012-08-10 09:29:36

imo即時通訊

2021-11-01 22:24:08

電腦配置設置

2014-09-24 13:08:35

微信企業號

2020-09-23 06:52:49

代碼方法模式

2022-11-07 11:42:36

人工智能機器人無人駕駛

2023-03-16 18:30:55

GPT-4ChatGPT

2022-04-26 14:14:32

數字人民幣支付數字化

2021-05-26 17:33:47

AI 數據人工智能

2021-05-10 19:17:54

GoInt128類型

2024-12-13 16:01:35

2025-07-29 09:36:51

2022-05-31 09:42:49

工具編輯器

2024-05-11 09:38:05

React編譯器React 19
點贊
收藏

51CTO技術棧公眾號

成人无码精品1区2区3区免费看 | 狠狠操精品视频| 免费看男男www网站入口在线 | 国产精品久久久久久久99| 欧美aaa免费| 亚洲不卡在线| 亚洲 欧美综合在线网络| 久久久精品国产一区二区三区| 久久精品视频2| 亚洲色图插插| 在线亚洲高清视频| 国产98在线|日韩| 极品国产91在线网站| 亚洲激情久久| 亚洲天堂av高清| 中文字幕第66页| 不卡福利视频| 北岛玲一区二区三区四区| 日韩av手机在线观看| 欧美成人免费观看视频| 国产精品手机在线播放| 欧美成人激情免费网| 妓院一钑片免看黄大片| wwww亚洲| 99国产精品一区| 91美女高潮出水| 中文字幕在线天堂| 亚洲三级视频| 欧美成人黑人xx视频免费观看| 中文字幕一区二区三区人妻电影| 成人噜噜噜噜| 精品视频在线视频| 日韩久久一级片| 视频国产一区二区三区| 国产精品1区2区3区在线观看| 日韩在线视频观看| 在线 丝袜 欧美 日韩 制服| 精品一区二区三区中文字幕在线| 欧美曰成人黄网| 免费无遮挡无码永久视频| 在线免费观看污| 一区免费观看视频| 色爱区成人综合网| 国产成人一级片| 午夜精品婷婷| 久久人人爽人人爽爽久久 | 日本一区二区视频在线| 国产福利成人在线| 日韩精品久久久久久久酒店| 欧美不卡在线| 久久99热这里只有精品国产| 搜索黄色一级片| 久久中文视频| 北条麻妃久久精品| 精品人伦一区二区| 国产调教一区二区三区| 亚洲欧美制服第一页| 美国黄色a级片| 日韩影视在线观看| 日韩大片免费观看视频播放| 国产视频久久久久久| 国产suv精品一区| 亚洲高清久久网| 北岛玲一区二区| 日韩av网址大全| 亚洲欧美在线x视频| 色一情一区二区三区| www国产在线观看| 亚洲日本一区二区| 在线视频亚洲自拍| 天堂成人在线视频| 99国产精品久久| 久久精品国产一区二区三区日韩| 涩爱av在线播放一区二区| 久久综合久久鬼色中文字| 免费在线国产精品| 成人动漫在线免费观看| 中文字幕一区二区三区乱码在线| 国产区一区二区三区| 视频污在线观看| 久久蜜桃香蕉精品一区二区三区| 日韩精彩视频| 欧美一级性视频| 91片在线免费观看| 日韩中文字幕av在线| 日本www在线观看| 99久久夜色精品国产网站| 久久综合九色综合网站| avtt在线播放| 夜夜嗨av一区二区三区| 大陆极品少妇内射aaaaa| 欧美aa视频| 欧美精选午夜久久久乱码6080| 在线观看视频你懂得| 青草久久视频| 色偷偷偷亚洲综合网另类 | 66国产精品| 性欧美视频videos6一9| 亚洲av无码乱码国产精品fc2| 激情综合网最新| 国产亚洲欧美一区二区| 亚乱亚乱亚洲乱妇| 亚洲r级在线视频| 激情黄色小视频| 老司机在线精品视频| 亚洲一区二区精品| 国产伦精品一区二区免费| 美女毛片一区二区三区四区| 337p日本欧洲亚洲大胆色噜噜| 欧美色图亚洲激情| 亚洲欧美一级二级三级| 日韩美女视频在线观看| 精品黑人一区二区三区在线观看| 美女任你摸久久| 粉嫩av免费一区二区三区| 成人一区二区不卡免费| 亚洲h动漫在线| 无套内谢丰满少妇中文字幕| 自拍偷拍一区| 一道本无吗dⅴd在线播放一区 | 国产日韩欧美黄色| 亚洲 另类 春色 国产| 亚洲男人的天堂在线观看| 嫩草av久久伊人妇女超级a| 国产精品任我爽爆在线播放| 久久亚洲精品一区二区| 在线免费av网| 久久女同性恋中文字幕| 蜜臀av色欲a片无码精品一区| 亚洲精品毛片| 一本色道久久88综合亚洲精品ⅰ| 中文字幕亚洲精品一区| 国产美女娇喘av呻吟久久| 亚洲精品日韩成人| 欧美日韩免费观看视频| 日韩成人av在线| 久久久久亚洲av片无码下载蜜桃| 精品一区二区在线播放| 亚洲欧洲免费无码| 韩日精品一区| 一区二区亚洲欧洲国产日韩| 国产三级精品三级在线观看| 99久久er热在这里只有精品15 | 男人的午夜天堂| 奇米888四色在线精品| 国产狼人综合免费视频| 视频一区二区在线播放| 精品欧美国产一区二区三区| 中国特级黄色大片| 国自产拍偷拍福利精品免费一| 91嫩草国产在线观看| 中文字幕伦理免费在线视频 | 成人资源av| 国产探花在线观看| 精品电影一区二区| 男女视频免费看| 99国产精品国产精品毛片| 免费av观看网址| 天堂成人娱乐在线视频免费播放网站| 88国产精品欧美一区二区三区| 天天爽夜夜爽夜夜爽| 五月激情六月综合| 亚洲欧美视频在线播放| 久久xxxx| 亚洲精品一区国产精品| 亚洲18在线| 久久91精品国产| 日本高清视频免费观看| 日韩欧美在线视频免费观看| 亚洲の无码国产の无码步美| 久久久久久9| 亚洲欧洲免费无码| 一区二区亚洲视频| 欧美最猛性xxxxx亚洲精品| 国产日韩精品在线看| 亚洲精品国产无天堂网2021| 91丨porny丨九色| 亚洲激情一区| 日韩中文字幕av在线| 91九色成人| 国外成人免费在线播放| 一个人看的www日本高清视频| 国产精品每日更新| 欧美xxxx黑人| 香蕉久久国产| 中文字幕日韩精品久久| 日韩中文字幕视频网| 2019最新中文字幕| 丁香婷婷在线| 欧美不卡视频一区| 日韩在线 中文字幕| 亚洲欧洲99久久| 五月婷婷综合在线观看| 久久av资源网| 亚洲 欧美 日韩 国产综合 在线 | 欧美亚男人的天堂| 丰满少妇高潮久久三区| 久久一夜天堂av一区二区三区| www.超碰97.com| 日韩一级大片| 国产精品jizz在线观看老狼| 欧美男男freegayvideosroom| 国产精品网址在线| 操人在线观看| 久久精品国产99国产精品澳门| 天天操天天干天天爽| 91精品国产免费| 中文字幕 国产精品| 亚洲一区二区三区中文字幕 | 五月婷婷另类国产| 精品人体无码一区二区三区| 不卡影院免费观看| 一区二区三区四区毛片| 久久久精品午夜少妇| 蜜臀av无码一区二区三区| 国产精品国产三级国产在线观看 | 欧美日韩综合| 亚洲精品中字| 一区三区在线欧| 国产区欧美区日韩区| 国模大尺度视频一区二区| 国产精品草莓在线免费观看 | 一区二区成人精品| 天天干在线观看| 欧美成人乱码一区二区三区| 亚洲天堂999| 在线视频综合导航| 久久久久女人精品毛片九一 | 国产污视频网站| 午夜精品免费在线| 国产小视频在线看| 亚洲男女一区二区三区| jizzjizz日本少妇| 国产人久久人人人人爽| 欧美 日本 国产| 成人午夜看片网址| 69久久精品无码一区二区| 极品美女销魂一区二区三区| 欧美三级午夜理伦三级富婆| 老**午夜毛片一区二区三区| 男人天堂网视频| 妖精视频成人观看www| 日本黄大片在线观看| 欧美福利影院| 成人免费看片'免费看| 欧美 亚欧 日韩视频在线| 一区二区成人国产精品| 成人黄色小视频| 成人国产精品一区| 99久久亚洲国产日韩美女| www.欧美精品| 无遮挡动作视频在线观看免费入口| 亚洲男人的天堂在线| 免费在线观看污视频| 亚洲欧美国产一本综合首页| 男女视频在线观看免费| 亚洲一区二区久久| av网站在线免费播放| 色噜噜亚洲精品中文字幕| 国产99久久久欧美黑人| 白白操在线视频| 国产精品99视频| 欧洲精品视频在线| 国产成人a视频高清在线观看| 26uuu亚洲伊人春色| 国产精品一区二区av影院萌芽| 国产91精品在线播放| 国产一区二区三区四区五区3d| 国产欧美日韩中文字幕| 国产免费区一区二区三视频免费| 999热视频| 国产精品视频3p| 日本日本精品二区免费| 精品国产亚洲一区二区三区在线| 亚洲在线第一页| 精品欧美午夜寂寞影院| 日韩国产一区久久| 欧美国产美女| 在线观看日韩羞羞视频| 午夜精品视频一区二区三区在线看| 三级在线免费观看| 亚洲视频播放| 日日鲁鲁鲁夜夜爽爽狠狠视频97| 日韩专区一卡二卡| 在线a免费观看| 91毛片在线观看| 制服丨自拍丨欧美丨动漫丨| 亚洲一区二区三区在线| 精品无码一区二区三区的天堂| 91麻豆精品久久久久蜜臀| 精品1区2区| 成人好色电影| 欧美日韩福利视频| 中文字幕在线直播| 91欧美精品午夜性色福利在线| 欧美一区二区三区红桃小说| 亚洲日本精品一区| 亚洲精品孕妇| www.51色.com| 国产亚洲精品bt天堂精选| 欧美片一区二区| 欧美性xxxxx极品| 午夜免费福利视频| 中文国产成人精品| 国产区视频在线| 欧美精品精品精品精品免费| 99久久久国产精品免费调教网站| 国产精品一区二区a| 久久大综合网| 欧美日韩在线中文| 国产精品一二三四五| 91麻豆制片厂| 中文天堂在线一区| 日韩av片在线播放| 日韩一区二区中文字幕| 极品白浆推特女神在线观看| 欧美黑人性猛交| 日韩美女在线| 日韩啊v在线| 亚洲欧美日本视频在线观看| 超碰人人cao| 中文字幕亚洲区| 亚洲国产成人精品女人久久| 亚洲国产私拍精品国模在线观看| 91网址在线观看| 国产在线拍偷自揄拍精品| 国产真实有声精品录音| 国产91对白刺激露脸在线观看| 国产成人精品亚洲日本在线桃色 | 久久av网站| 亚洲天堂电影网| 日韩av一区二区在线影视| 特级西西人体wwwww| 亚洲一区二区三区自拍| 成人黄色免费视频| 欧美成人网在线| 精品亚洲a∨一区二区三区18| 26uuu成人| 国精产品一区一区三区mba视频| 超碰人人人人人人人| 欧洲一区在线电影| 国产香蕉在线| 国产精品网红福利| 国产精品精品国产一区二区| 午夜宅男在线视频| 狠狠色丁香婷婷综合久久片| 欧美人妻一区二区三区| 91久久精品一区二区| 九一国产在线| 日韩美女写真福利在线观看| 免费欧美激情| 国产成人精品视频ⅴa片软件竹菊| 久久免费偷拍视频| 亚洲精品一区二三区| 自拍偷拍亚洲在线| 欧美一区二区三区婷婷| av不卡在线免费观看| 国产99久久久国产精品潘金 | 欧美午夜精品久久久久久超碰| 国产污视频在线| 国产欧美日韩专区发布| 久久久人成影片免费观看| 熟妇无码乱子成人精品| 亚洲二区在线视频| 国产黄色免费视频| 国产亚洲精品久久| 激情中国色综合| 欧美 亚洲 视频| 成人爱爱电影网址| 亚洲影院在线播放| 最近2019中文免费高清视频观看www99| 国模私拍国内精品国内av| 日本一道在线观看| www.亚洲激情.com| 337p粉嫩色噜噜噜大肥臀| 久久激情视频免费观看| 第一区第二区在线| 可以在线看的黄色网址| 国产精品的网站| 高潮一区二区三区乱码| 国产精品∨欧美精品v日韩精品| 欧美大黑bbbbbbbbb在线| av影片在线播放| 欧美午夜精品久久久久久浪潮| 天天综合视频在线观看| 99视频国产精品免费观看| 久久精品一区二区国产| 午夜精品福利在线视频| 国产丝袜一区二区三区| gogo大尺度成人免费视频| 日韩欧美视频网站| 一区在线播放视频| 欧洲一区av| 3d精品h动漫啪啪一区二区| 久久精品官网| 久久久久亚洲av无码专区体验| 亚洲免费精彩视频| 精品视频在线观看网站| 成人黄色一区二区| 亚洲国产精品一区二区久久 |