設計模式(一) 策略模式

 

使用場景

定義一系列的算法,將算法進行封裝、隔離、相互獨立、又能相互替換。算法

公司最近在作直播功能,底層原來有一套直播API,如今新增一套網宿直播API。
考慮之後的擴展性,須要將兩套API進行統一管理。如今以網上的支付方式演示我對策略模式的理解。
微信

支付方式

咱們知道網上有不少支付方式。支付寶、微信、銀行卡、花唄...
咱們以三種支付方式進行演示。
ide

 

策略模式的組成有三部分微信支付

 

環境類(Context):用一個ConcreteStrategy對象來配置。維護一個對Strategy對象的引用。this

可定義一個接口來讓Strategy訪問它的數據,在上一個例子中至關於Staff。spa

抽象策略類(Strategy):定義全部支持的算法的公共接口。 Context使用這個接口來調用某ConcreteStrategy定義的算法,調試

在上一個例子中至關於GrantReward。
具體策略類(ConcreteStrategy):以Strategy接口實現某具體算法,在上一個例子中至關於GrantSuger,GrantMoonCake,GrantNone。
code

 

支付方式的組成也有三部分
對象

 

支付策略接口(PayStrategy):定義支付方式
具體支付方式(AliPayStrategy、WxPayStrategy、CardPayStrategy):具體的支付算法
支付策略上下文(PayStrategyContent):管理全部支付方式的引用,並根據用戶選擇引用對應的支付方式。
blog

 

代碼實現

 

支付策略接口(PayStrategy)

 1 /**  2  * 支付策略接口  3  * @author JinXing  4  * @date 2019/7/12 13:58  5 */  6 public interface PayStrategy {  7  8  9 10 /** 11  * 12  * 選擇支付方式 13  * 支付寶 14  * 微信 15  * 銀行卡 16  * @return RemoteResult 17 */ 18 RemoteResult<String> toPayHtml(); 19 20 21 }

 

 

具體支付方式(AliPayStrategy)

 1 /**  2  * 阿里pay  3  * @author JinXing  4  * @date 2019/7/12 14:36  5 */  6 @Service  7 public class AliPayStrategy implements PayStrategy {  8  9  @Override 10 public RemoteResult<String> toPayHtml() { 11 12 System.out.println("如今採用的支付方式爲:支付寶支付......"); 13 14 return null; 15  } 16 }

 

具體支付方式(WxPayStrategy)

 1 /**  2  * 微信支付  3  * @author JinXing  4  * @date 2019/7/12 14:36  5 */  6  7 @Service  8 public class WxPayStrategy implements PayStrategy {  9 10  @Override 11 public RemoteResult<String> toPayHtml() { 12 13 System.out.println("如今採用的支付方式爲:微信支付......"); 14 15 return null; 16  } 17 }

 

具體支付方式(CardPayStrategy)

 1 /**  2  * 銀行卡支付  3  * @author JinXing  4  * @date 2019/7/12 14:36  5 */  6  7 @Service  8 public class CardPayStrategy implements PayStrategy {  9 10  @Override 11 public RemoteResult<String> toPayHtml() { 12 13 System.out.println("如今採用的支付方式爲:銀行卡支付......"); 14 15 return null; 16  } 17 }

 

支付策略上下文(PayStrategyContent)

/** * 支付策略上下文 * @author JinXing * @date 2019/7/12 14:39 */ @Component public class PayStrategyContent { /** 策略實例集合 */ private ConcurrentHashMap<String, PayStrategy> strategyMap = new ConcurrentHashMap<>(20); /** * 注入策略實例 * 若是使用的是構造器注入,可能會有多個參數注入進來。 * * 若是使用的是field反射注入 * * 若是使用的是setter方法注入,那麼你將不能將屬性設置爲final。 * * @param strategyMap * 注意注入類型要是Map基礎類型 */ @Autowired public PayStrategyContent(Map<String, PayStrategy> strategyMap) { //清空集合數據 this.strategyMap.clear(); if (!CollectionUtils.isEmpty(strategyMap)) { strategyMap.forEach((beanName, payStrategy) -> { if (StringUtils.isEmpty(beanName) || payStrategy == null) { return; } this.strategyMap.put(beanName.toLowerCase(), payStrategy); }); } } /** * 選擇支付方式 * 支付寶、微信、銀行卡 * * @param paymentEnums * * @return RemoteResult */ RemoteResult<String> toPayHtml(PaymentEnums paymentEnums) { if (CollectionUtils.isEmpty(strategyMap)) { return new RemoteResult<String>().error("策略實例集合初始化失敗,請檢查是否正確注入!"); } return this.strategyMap.get(paymentEnums.getBeanName()).toPayHtml(); } }

 

支付方式枚舉(PaymentEnums)

 1 /**
 2  * 支付方式枚舉對象
 3  * code -> 支付方式別名
 4  * beanName -> 實例的名稱
 5  *
 6  * @author JinXing
 7  * @date 2019/7/12 14:40
 8  */
 9 public enum PaymentEnums {
10 
11     /** 支付方式 */
12     ALI_PAY("ali_pay", AliPayStrategy.class.getSimpleName()),
13     WX_PAY("WX_PAY", WxPayStrategy.class.getSimpleName()),
14     CARD_PAY("card_pay", CardPayStrategy.class.getSimpleName()),
15 
16     ;
17 
18     /** 枚舉定義+描述 */
19     private String code;
20     private String beanName;
21 
22     PaymentEnums(String code, String beanName) {
23         this.code = code;
24         this.beanName = StringUtils.isNotEmpty(beanName)?beanName.toLowerCase():null;
25     }
26 
27 
28     /** 根據code獲取對應的枚舉對象 */
29     public static PaymentEnums getEnum(String code) {
30         PaymentEnums[] values = PaymentEnums.values();
31         if (null != code && values.length > 0) {
32             for (PaymentEnums value : values) {
33                 if (value.code.equals(code)) {
34                     return value;
35                 }
36             }
37         }
38         return null;
39     }
40 
41     /** 該code在枚舉列表code屬性是否存在 */
42     public static boolean containsCode(String code) {
43         PaymentEnums anEnum = getEnum(code);
44         return anEnum != null;
45     }
46 
47     /** 判斷code與枚舉中的code是否相同 */
48     public static boolean equals(String code, PaymentEnums calendarSourceEnum) {
49         return calendarSourceEnum.code.equals(code);
50     }
51 
52 
53     public String getCode() {
54         return code;
55     }
56 
57     public String getBeanName() {
58         return beanName;
59     }
60 }

 

結果集包裝類(RemoteResult)

 1 /**  2  * <pre>  3  * 遠程接口值對象,此對象使用說明  4  * 使用時,判斷isSuccess返回值,true表示業務成功、false表示接口調用失敗  5  * errorCode,用於判斷失敗緣由(非系統錯誤),系統預設錯誤碼,用負數表示:-1表示參數不合法,用戶自定義錯誤碼使用正數表示,0表示無錯誤  6  * </pre>  7  *  8  * @author jx  9  * @param <T> 10 */ 11 12 13 public class RemoteResult<T> implements Serializable { 14 15 private static final long serialVersionUID = 1L; 16 /** 接口調用是否成功(業務),系統錯誤、業務失敗都將返回false */ 17 private boolean isSuccess = true; 18 /** 自定義錯誤信息,發生可處理錯誤時,返回自定義信息 */ 19 private String errorMsg = "ok"; 20 /** 接口返回結果(Void表示無返回值) */ 21 private T result; 22 /** 異常堆棧信息,須要提供調試功能時,將異常加入此堆棧中,便於協調調用方調試,僅做調試用 */ 23 private Exception exceptionStack; 24 25 public RemoteResult() { 26  } 27 28 public RemoteResult<T> error(String errorMsg) { 29 this.errorMsg = errorMsg; 30 this.isSuccess = false; 31 return this; 32  } 33 34 public static long getSerialVersionUID() { 35 return serialVersionUID; 36  } 37 38 public boolean isSuccess() { 39 return isSuccess; 40  } 41 42 public void setSuccess(boolean success) { 43 isSuccess = success; 44  } 45 46 public String getErrorMsg() { 47 return errorMsg; 48  } 49 50 public void setErrorMsg(String errorMsg) { 51 this.errorMsg = errorMsg; 52  } 53 54 public T getResult() { 55 return result; 56  } 57 58 public void setResult(T result) { 59 this.result = result; 60  } 61 62 public Exception getExceptionStack() { 63 return exceptionStack; 64  } 65 66 public void setExceptionStack(Exception exceptionStack) { 67 this.exceptionStack = exceptionStack; 68  } 69 70 }
相關文章
相關標籤/搜索