什么是模版方法
1.定义了一个操作中的算法的骨架,而将部分步骤的实现在子类中完成。
模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
2.模板方法模式是所有模式中最为常见的几个模式之一,是基于继承的代码复用的基本技术,没有关联关系。 因此,在模板方法模式的类结构图中,只有继承关系。
核心设计要点:
AbstractClass : 抽象类,定义并实现一个模板方法。这个模板方法定义了算法的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类去实现
ConcreteClass : 实现实现父类所定义的一个或多个抽象方法。
模版方法应用场景
- 比如聚合支付平台中系统回调代码重构
- Servlet 请求
模版方法抽象类
1 @Slf4j 2 @Component 3 public abstract class AbstractPayCallbackTemplate { 4 5 /** 6 * 异步回调业务 7 * 8 * @return 9 */ 10 public String asyncCallBack() { 11 // 1. 支付回调验证参数 12 Map<String, String> verifySignatureMap = verifySignature(); 13 // 2. 参数验证成功,写入日志中.. 14 payLog(verifySignatureMap); 15 String analysisCode = verifySignatureMap.get("analysisCode"); 16 if (!analysisCode.equals("200")) { 17 return resultFail(); 18 } 19 // 3. 执行回调异步相关逻辑 20 return asyncService(verifySignatureMap); 21 22 } 23 24 25 /** 26 * 支付回调验证参数 27 * 28 * @return 29 */ 30 protected abstract Map<String, String> verifySignature(); 31 32 /** 33 * 使用多线程异步写入日志 34 * 35 * @param verifySignatureMap 36 */ 37 @Async 38 private void payLog(Map<String, String> verifySignatureMap) { 39 log.info(">>>>>>>>>>第二步 写入payLog........"); 40 } 41 42 /** 43 * 每个子类需要实现 实现业务解析操作 44 * 45 * @return 46 */ 47 protected abstract String asyncService(Map<String, String> verifySignatureMap); 48 49 /** 50 * 异步返回结果.. 51 * 52 * @return 53 */ 54 protected abstract String resultSuccess(); 55 56 /** 57 * 异步返回失败 58 * 59 * @return 60 */ 61 protected abstract String resultFail(); 62 }
具体实现模版
支付宝回调 伪代码
1 @Component 2 @Slf4j 3 public class AliPayCallbackTemplate extends AbstractPayCallbackTemplate { 4 @Override 5 protected Map<String, String> verifySignature() { 6 //>>>>假设一下为银联回调报文>>>>>>>>>>>>>>>> 7 log.info(">>>>>第一步 解析支付宝据报文.....verifySignature()"); 8 Map<String, String> verifySignature = new HashMap<>(); 9 verifySignature.put("price", "1399"); 10 verifySignature.put("orderDes", "充值CC大课堂永久会员"); 11 // 支付状态为1表示为成功.... 12 verifySignature.put("aliPayMentStatus", "1"); 13 verifySignature.put("aliPayOrderNumber", "201910101011"); 14 // 解析报文是否成功 200 为成功.. 15 verifySignature.put("analysisCode", "200"); 16 return verifySignature; 17 } 18 19 @Override 20 protected String asyncService(Map<String, String> verifySignatureMap) { 21 log.info(">>>>>第三步asyncService()verifySignatureMap:{}", verifySignatureMap); 22 String paymentStatus = verifySignatureMap.get("aliPayMentStatus"); 23 if (paymentStatus.equals("1")) { 24 String aliPayOrderNumber = verifySignatureMap.get("aliPayOrderNumber"); 25 log.info(">>>>orderNumber:{aliPayOrderNumber},已经支付成功 修改订单状态为已经支付..."); 26 } 27 return resultSuccess(); 28 } 29 30 @Override 31 protected String resultSuccess() { 32 return "ok"; 33 } 34 }
银联支付回调 伪代码
1 @Component 2 @Slf4j 3 public class UnionPayCallbackTemplate extends AbstractPayCallbackTemplate { 4 @Override 5 protected Map<String, String> verifySignature() { 6 //>>>>假设一下为银联回调报文>>>>>>>>>>>>>>>> 7 log.info(">>>>>第一步 解析银联数据报文.....verifySignature()"); 8 Map<String, String> verifySignature = new HashMap<>(); 9 verifySignature.put("price", "1399"); 10 verifySignature.put("orderDes", "充值CC大课堂永久会员"); 11 // 支付状态为1表示为成功.... 12 verifySignature.put("paymentStatus", "1"); 13 verifySignature.put("orderNumber", "201910101011"); 14 // 解析报文是否成功 200 为成功.. 15 verifySignature.put("analysisCode", "200"); 16 return verifySignature; 17 } 18 19 @Override 20 protected String asyncService(Map<String, String> verifySignatureMap) { 21 log.info(">>>>>第三步asyncService()verifySignatureMap:{}", verifySignatureMap); 22 String paymentStatus = verifySignatureMap.get("paymentStatus"); 23 if (paymentStatus.equals("1")) { 24 String orderNumber = verifySignatureMap.get("orderNumber"); 25 log.info(">>>>orderNumber:{orderNumber},已经支付成功 修改订单状态为已经支付..."); 26 } 27 return resultSuccess(); 28 } 29 30 @Override 31 protected String resultSuccess() { 32 return "success"; 33 } 34 }
工厂模式获取模版
1 public class TemplateFactory { 2 3 public static AbstractPayCallbackTemplate getPayCallbackTemplate(String templateId) { 4 AbstractPayCallbackTemplate payCallbackTemplate = (AbstractPayCallbackTemplate) SpringUtils.getBean(templateId); 5 return payCallbackTemplate; 6 } 7 }
模式模式优缺点
1.)优点
模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。子类实现算法的某些细节,有助于算法的扩展。通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。
2.)缺点
每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。
3.)适用场景
在某些类的算法中,用了相同的方法,造成代码的重复。控制子类扩展,子类必须遵守算法规则。