非同步回撥流程
解析報文(驗證簽名)
日誌收集(相同)
如果解析報文成功的話,修改支付狀態為已經成功.返回不同的支付結果
模版方法設計模式
提前定義好整體的骨架,不同的行為讓子類實現,相同的行為直接定義在抽象類中複用。
相同的行為就定在抽象方案中,不同的行為的實現子類實現
核心設計要點
AbstractClass : 抽象類,定義並實現一個模板方法。這個模板方法定義了演算法的骨架,而邏輯的組成步驟在相應的抽象操作中,推遲到子類去實現。ConcreteClass : 實現父類所定義的一個或多個抽象方法。
模版方法抽象類
/** * * @description: 使用模版方法重構非同步回撥程式碼 */@Slf4j@Componentpublic abstract class AbstractPayCallbackTemplate { /** * 非同步回撥業務 */ public String asyncCallBack() { // 1. 支付回撥驗證引數 Map<String, String> verifySignatureMap = verifySignature(); // 2. 引數驗證成功,寫入日誌中 payLog(verifySignatureMap); String analysisCode = verifySignatureMap.get("analysisCode"); if (!analysisCode.equals(PayConstant.RESULT_PAYCODE_200)) { return resultFail(); } // 3. 執行回撥非同步相關邏輯 return asyncService(verifySignatureMap); } /** * 使用多執行緒非同步寫入日誌 */ @Async protected void payLog(Map<String,String> verifySignatureMap){ log.info(">>>>>>>>>>第二步 寫入payLog........{}",verifySignatureMap); } /** * 實現業務解析操作 */ protected abstract String asyncService(Map<String,String> verifySignatureMap); /** * 非同步返回成功結果 */ protected abstract String resultSuccess(); /** * 非同步返回失敗結果 */ protected abstract String resultFail(); /** * 支付回撥驗證引數 */ protected abstract Map<String,String> verifySignature();}
具體實現模版①AliPayCallbackTemplate
/** * @title: AliPayCallbackTemplate */@Component@Slf4jpublic class AliPayCallbackTemplate extends AbstractPayCallbackTemplate { @Override protected Map<String, String> verifySignature() { //>>>>支付寶回撥報文虛擬碼>>>> log.info(">>>>>第一步 解析支付寶資料報文.....verifySignature()"); Map<String, String> verifySignature = new HashMap<>(); verifySignature.put("price", "10000"); verifySignature.put("orderDes", "充值會員"); // 支付狀態為1表示為成功.... verifySignature.put("aliPayMentStatus", "1"); verifySignature.put("aliPayOrderNumber", "20190511"); // 解析報文是否成功 200 為成功.. verifySignature.put("analysisCode", PayConstant.RESULT_PAYCODE_200); return verifySignature; } @Override protected String asyncService(Map<String, String> verifySignatureMap) { log.info(">>>>>第三步asyncService()verifySignatureMap:{}", verifySignatureMap); String paymentStatus = verifySignatureMap.get("aliPayMentStatus"); if (paymentStatus.equals("1")) { String aliPayOrderNumber = verifySignatureMap.get("aliPayOrderNumber"); log.info(">>>>orderNumber:{aliPayOrderNumber},已經支付成功 修改訂單狀態為已經支付..."); } return resultSuccess(); } @Override protected String resultSuccess() { return PayConstant.ALIPAY_RESULT_SUCCESS; } @Override protected String resultFail() { return PayConstant.ALIPAY_RESULT_FAIL; }}
②UnionPayCallbackTemplate
/** * @title: UnionPayCallbackTemplate */@Component@Slf4jpublic class UnionPayCallbackTemplate extends AbstractPayCallbackTemplate { @Override protected Map<String, String> verifySignature() { //>>>>銀聯回撥報文虛擬碼>>>>>>>> log.info(">>>>>第一步 解析銀聯資料報文.....verifySignature()"); Map<String, String> verifySignature = new HashMap<>(); verifySignature.put("price", "10000"); verifySignature.put("orderDes", "充值會員"); // 支付狀態為1表示為成功.... verifySignature.put("paymentStatus", "1"); verifySignature.put("orderNumber", "20190511"); // 解析報文是否成功 200 為成功.. verifySignature.put("analysisCode", PayConstant.RESULT_PAYCODE_200); return verifySignature; } @Override protected String asyncService(Map<String, String> verifySignatureMap) { log.info(">>>>>第三步asyncService()verifySignatureMap:{}", verifySignatureMap); String paymentStatus = verifySignatureMap.get("paymentStatus"); if (paymentStatus.equals(PayConstant.PAY_STATUS_SUCCESS)) { String orderNumber = verifySignatureMap.get("orderNumber"); log.info(">>>>orderNumber:{orderNumber},已經支付成功 修改訂單狀態為已經支付..."); } return resultSuccess(); } @Override protected String resultSuccess() { return PayConstant.UNION_RESULT_SUCCESS; } @Override protected String resultFail() { return PayConstant.UNION_RESULT_FAIL; }}
工廠模式獲取模版
/** * @title: TemplateFactory */public class TemplateFactory { public static AbstractPayCallbackTemplate getPayCallbackTemplate(String templateId) { AbstractPayCallbackTemplate payCallbackTemplate = (AbstractPayCallbackTemplate) SpringUtils.getBean(templateId); return payCallbackTemplate; }}
SpringUtils
@Componentpublic class SpringUtils implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } //獲取applicationContext public static ApplicationContext getApplicationContext() { return applicationContext; } //透過name獲取 Bean. public static Object getBean(String name) { return getApplicationContext().getBean(name); } //透過class獲取Bean. public static <T> T getBean(Class<T> clazz) { return getApplicationContext().getBean(clazz); } //透過name,以及Clazz返回指定的Bean public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); }}
相關依賴
/** * @title: TemplateController */@RestControllerpublic class TemplateController { @RequestMapping("/asyncCallBack") public String asyncCallBack(String templateId) { AbstractPayCallbackTemplate payCallbackTemplate = TemplateFactory.getPayCallbackTemplate(templateId); return payCallbackTemplate.asyncCallBack(); }}
程式入口
@SpringBootApplication@EnableAsyncpublic class AppTemplate { public static void main(String[] args) { SpringApplication.run(AppTemplate.class); }}
控制檯輸出結果
>>>>>第一步 解析支付寶據報文.....verifySignature()>>>>>第二步 寫入payLog........{aliPayOrderNumber=20190511, orderDes=充值會員, price=10000, analysisCode=200, aliPayMentStatus=1}>>>>>第三步asyncService()verifySignatureMap:{aliPayOrderNumber=20190511, orderDes=充值會員, price=10000, analysisCode=200, aliPayMentStatus=1}>>>>orderNumber:{aliPayOrderNumber},已經支付成功 修改訂單狀態為已經支付...
>>>>>第一步 解析銀聯資料報文.....verifySignature()>>>>>第二步 寫入payLog........{orderNumber=20190511, orderDes=充值會員, price=10000, analysisCode=200, paymentStatus=1}>>>>>第三步asyncService()verifySignatureMap:{orderNumber=20190511, orderDes=充值會員, price=10000, analysisCode=200, paymentStatus=1}
總結模版設計模式優缺點
1.優點模板方法模式透過把不變的行為搬移到超類,去除了子類中的重複程式碼。子類實現演算法的某些細節,有助於演算法的擴充套件。透過一個父類呼叫子類實現的操作,透過子類擴充套件增加新的行為,符合“開放-封閉原則”。2.缺點每個不同的實現都需要定義一個子類,這會導致類的個數的增加,設計更加抽象。3.適用場景在某些類的演算法中,用了相同的方法,造成程式碼的重複。控制子類擴充套件,子類必須遵守演算法規則。
工廠設計模式優缺點
優點:1.程式碼結構簡單。2.獲取產品的過程更加簡單。3.滿足了開閉原則,即對拓展開放,對修改關閉。缺點:拓展較繁瑣,要拓展時,需同時改動抽象工廠和工廠實現類。