您的位置:首页 > 职场人生

程序员突发奇想,如何巧用设计模式来实现【聚合支付异步回调】

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({});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: