程序员突发奇想,如何巧用设计模式来实现【聚合支付异步回调】
2019-05-12 07:21
1171 查看
什么是模版方法
1.定义了一个操作中的算法的骨架,而将部分步骤的实现在子类中完成。 模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 2.模板方法模式是所有模式中最为常见的几个模式之一,是基于继承的代码复用的基本技术,没有关联关系。 因此,在模板方法模式的类结构图中,只有继承关系。
核心设计要点
AbstractClass : 抽象类,定义并实现一个模板方法。这个模板方法定义了算法的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类去实现 ConcreteClass : 实现父类所定义的一个或多个抽象方法
模版方法应用场景
1.比如聚合支付平台中系统回调代码重构 2.Servlet 请求
模版方法抽象类
/** * * @description: 使用模版方法重构异步回调代码 */ @Slf4j @Component public 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(); }
具体实现模版
/** * @title: AliPayCallbackTemplate */ @Component @Slf4j public 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; } }
/** * @title: UnionPayCallbackTemplate */ @Component @Slf4j public 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; } }
支付相关常量数据
/** * 支付相关常量数据 */ public interface PayConstant { String RESULT_PAYCODE_200 = "200"; /** * 已经支付成功状态 */ Integer PAY_STATUS_SUCCESS = 1; /** * 返回银联通知成功 */ String UNION_RESULT_SUCCESS = "seccess"; /** * 返回支付宝通知成功 */ String ALIPAY_RESULT_SUCCESS = "ok"; /** * 返回银联失败通知 */ String UNION_RESULT_FAIL = "fail"; /** * 返回支付宝失败通知 */ String ALIPAY_RESULT_FAIL = "no"; }
工具类
@Component public 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 */ @RestController public class TemplateController { @RequestMapping("/asyncCallBack") public String asyncCallBack(String templateId) { AbstractPayCallbackTemplate payCallbackTemplate = TemplateFactory.getPayCallbackTemplate(templateId); return payCallbackTemplate.asyncCallBack(); } }
启动类
@SpringBootApplication @EnableAsync public class AppTemplate { public static void main(String[] args) { SpringApplication.run(AppTemplate.class); } }
pom依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <dependencies> <!-- sprinboot web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> </dependencies>
控制台输出结果
2019-05-11 23:23:30.420 INFO 27576 --- [nio-8080-exec-9] c.x.t.impl.AliPayCallbackTemplate : >>>>>第一步 解析支付宝据报文.....verifySignature() 2019-05-11 23:23:30.420 INFO 27576 --- [nio-8080-exec-9] c.x.t.AbstractPayCallbackTemplate : >>>>>>>>>>第二步 写入payLog........{aliPayOrderNumber=20190511, orderDes=充值会员, price=10000, analysisCode=200, aliPayMentStatus=1} 2019-05-11 23:23:30.420 INFO 27576 --- [nio-8080-exec-9] c.x.t.impl.AliPayCallbackTemplate : >>>>>第三步asyncService()verifySignatureMap:{aliPayOrderNumber=20190511, orderDes=充值会员, price=10000, analysisCode=200, aliPayMentStatus=1} 2019-05-11 23:23:30.420 INFO 27576 --- [nio-8080-exec-9] c.x.t.impl.AliPayCallbackTemplate : >>>>orderNumber:{aliPayOrderNumber},已经支付成功 修改订单状态为已经支付... 2019-05-11 23:23:32.710 INFO 27576 --- [io-8080-exec-10] c.x.t.impl.UnionPayCallbackTemplate : >>>>>第一步 解析银联数据报文.....verifySignature() 2019-05-11 23:23:32.710 INFO 27576 --- [io-8080-exec-10] c.x.t.AbstractPayCallbackTemplate : >>>>>>>>>>第二步 写入payLog........{orderNumber=20190511, orderDes=充值会员, price=10000, analysisCode=200, paymentStatus=1} 2019-05-11 23:23:32.710 INFO 27576 --- [io-8080-exec-10] c.x.t.impl.UnionPayCallbackTemplate : >>>>>第三步asyncService()verifySignatureMap:{orderNumber=20190511, orderDes=充值会员, price=10000, analysisCode=200, paymentStatus=1}
模版设计模式优缺点
1.优点 模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。子类实现算法的某些细节,有助于算法的扩展。通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。 2.缺点 每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。 3.适用场景 在某些类的算法中,用了相同的方法,造成代码的重复。控制子类扩展,子类必须遵守算法规则。
工厂设计模式优缺点
优点: 1.代码结构简单。 2.获取产品的过程更加简单。 3.满足了开闭原则,即对拓展开放,对修改关闭。 缺点: 拓展较繁琐,要拓展时,需同时改动抽象工厂和工厂实现类。
(adsbygoogle = window.adsbygoogle || []).push({});
相关文章推荐
- 设计模式的应用-策略模式实现支付方式回调策略
- 看老外程序员如何向妻子解释设计模式
- 看老外程序员如何向妻子解释设计模式
- 看老外程序员如何向妻子解释设计模式
- 设计模式-观察者模式,以及如何使用观察者来为app实现即时通讯功能
- 看老外程序员如何向妻子解释设计模式
- PHP微信支付开发之扫描支付(模式二)后如何回调
- 微信扫码支付模式二功能实现,回调,记录充值,整个完整流程,java开发
- 看老外程序员如何向妻子解释设计模式
- 如何用C实现一个类以及些许设计模式
- JavaScript是单线程运行的,但是ajax是如何实现的异步函数回调的?
- c++实现半同步半异步I/O的设计模式(half sync/half async)
- JAVA微信扫码支付模式二功能实现以及回调
- 如何用设计模式变相实现类的多继承?
- 看老外程序员如何向妻子解释设计模式
- 设计模式中聚合和组合--代码中的实现
- 设计模式之UML(一)类图以及类间关系(泛化 、实现、依赖、关联、聚合、组合)
- 设计模式之UML(一)类图以及类间关系(泛化 、实现、依赖、关联、聚合、组合)
- JAVA微信扫码支付模式二功能实现以及回调
- 基于生产-消费者模式的任务异步线程池设计与实现