1.什么是模板方法模式
定义共同的骨架,相同的行为定义在抽象方法中,不同的行为让子类实现
2.模板方法与策略模式的区别
策略是针对不同骨架、模板方法针对相同骨架。
3.应用场景
servlet中doGet doPost方法
4.模板方法实现
链接:https://pan.baidu.com/s/1_7uiMVVEVLjOVau6yplLSQ
提取码:huyi
1)pom依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<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>
2)抽象模板
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
@Slf4j
public abstract class AbstractPayCallbackTemplate {
/**
* 定义共同行为的骨架
* @return
*/
public String asyncCallBack() {
// 1.验证参数和验证签名
Map<String, String> verifySignature = verifySignature();
// 2.日志收集 相同
payLog(verifySignature);
// 3. 获取验证签名状态
if (!"200".equals(verifySignature.get("analysisCode"))) {
return resultFail();
}
// 4.更改数据库状态同时返回不同支付结果
return asyncService(verifySignature);
}
/**
* 使用多线程异步写入日志
* @param verifySignature
*/
public void payLog(Map<String, String> verifySignature) {
log.info(">>>>>第二步 写入数据库....verifySignature:{}", verifySignature);
}
/**
* 验证参数...
* @return
*/
protected abstract Map<String, String> verifySignature();
/**
* 执行修改订单状态和返回不用的结果..
* @param verifySignature
* @return
*/
protected abstract String asyncService(Map<String, String> verifySignature);
/**
* 返回失败结果
* @return
*/
protected abstract String resultFail();
/**
* 返回成功结果
* @return
*/
protected abstract String resultSuccess();
}
3)具体模板实现
import com.demo.template.AbstractPayCallbackTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Component
public class UnionPayCallbackTemplate extends AbstractPayCallbackTemplate {
@Override
protected Map<String, String> verifySignature() {
log.info(">>>>>第一步 解析银联据报文.....verifySignature()");
Map<String, String> verifySignature = new HashMap<>();
verifySignature.put("price", "1399");
verifySignature.put("orderDes", "test");
// 支付状态为1表示为成功....
verifySignature.put("unionPayMentStatus", "1");
verifySignature.put("unionPayOrderNumber", "201910101011");
// 解析报文是否成功 或者验证签名成功返回 200 为成功..
verifySignature.put("analysisCode", "200");
return verifySignature;
}
@Override
protected String asyncService(Map<String, String> verifySignature) {
log.info(">>>>>第三步 银联回调 asyncService()verifySignatureMap:{}", verifySignature);
String paymentStatus = verifySignature.get("unionPayMentStatus");
if (paymentStatus.equals("1")) {
String aliPayOrderNumber = verifySignature.get("aliPayOrderNumber");
log.info(">>>>orderNumber:{aliPayOrderNumber},已经支付成功 修改订单状态为已经支付..." + aliPayOrderNumber);
}
return resultSuccess();
}
@Override
protected String resultFail() {
return "fail";
}
@Override
protected String resultSuccess() {
return "success";
}
}
import com.demo.template.AbstractPayCallbackTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Component
public class AliPayCallbackTemplate extends AbstractPayCallbackTemplate {
@Override
protected Map<String, String> verifySignature() {
log.info(">>>>>第一步 解析支付宝据报文.....verifySignature()");
Map<String, String> verifySignature = new HashMap<>();
verifySignature.put("price", "1399");
verifySignature.put("orderDes", "ces");
// 支付状态为1表示为成功....
verifySignature.put("aliPayMentStatus", "1");
verifySignature.put("aliPayOrderNumber", "201910101011");
// 解析报文是否成功 或者验证签名成功返回 200 为成功..
verifySignature.put("analysisCode", "200");
return verifySignature;
}
@Override
protected String asyncService(Map<String, String> verifySignature) {
log.info(">>>>>第三步 支付宝支付 asyncService()verifySignatureMap:{}", verifySignature);
String paymentStatus = verifySignature.get("aliPayMentStatus");
if (paymentStatus.equals("1")) {
String aliPayOrderNumber = verifySignature.get("aliPayOrderNumber");
log.info(">>>>orderNumber:{aliPayOrderNumber},已经支付成功 修改订单状态为已经支付..." + aliPayOrderNumber);
}
return resultSuccess();
}
@Override
protected String resultFail() {
return "fail";
}
@Override
protected String resultSuccess() {
return "success";
}
}
4)工具类
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@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);
}
}
5)工厂
import com.demo.template.AbstractPayCallbackTemplate;
import com.demo.utils.SpringUtils;
public class TemplateFactory {
/**
* 使用工厂模式获取模版
* @param templateId
* @return
*/
public static AbstractPayCallbackTemplate getPayCallbackTemplate(String templateId) {
AbstractPayCallbackTemplate payCallbackTemplate = (AbstractPayCallbackTemplate)SpringUtils.getBean(templateId);
return payCallbackTemplate;
}
}
6)控制层
import com.demo.factory.TemplateFactory;
import com.demo.template.AbstractPayCallbackTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TemplateController {
/**
* 支付回调
* @return
*/
@RequestMapping("/asyncCallBack")
public String asyncCallBack(String templateId) {
AbstractPayCallbackTemplate payCallbackTemplate = TemplateFactory.getPayCallbackTemplate(templateId);
// 使用模版方法模式 执行共同的骨架
return payCallbackTemplate.asyncCallBack();
}
}
7)启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AppTemplate {
public static void main(String[] args) {
SpringApplication.run(AppTemplate.class);
}
}
8)测试
http://localhost:8080/asyncCallBack?templateId=unionPayCallbackTemplate