1、什么是模板方法模式
    定义了一个操作中的算法骨架,而将部分步骤的实现在子类完成。是最常见的设计模式,是基于继承的代码复用的技术,因此在模板方法类模型中只有继承关系。

    2、模板方法模式类结构图
    AbstractClass:抽象类,定义并实现一个模板方法,这个模板方法定义了算法的骨架,而抽象的逻辑步骤在相应的抽象操作中,推迟到子类去实现。

    ConcreteClass:实现父类定义的一个或多个抽象方法。

    3、优点:
    通过把不变的行为放到超类,去除了子类中的重复代码。子类实现算法中的某些细节,有助于算法扩展,通过子类来增加新的行为,符合开闭原则。

    缺点:
    每个不同的实现都需要定义一个子类,这样会导致类的个数增加,设计更加抽象。

    4、模板方法模式应用场景
    比如聚合支付平台中系统回调代码的重构

    模板方法抽象类

    1. @Slf4j
    2. @Component
    3. public abstract class AbstractPayCallbackTemplate {
    4. /**
    5. * 异步回调业务
    6. *
    7. * @return
    8. */
    9. public String asyncCallBack() {
    10. // 1. 支付回调验证参数
    11. Map<String, String> verifySignatureMap = verifySignature();
    12. // 2. 参数验证成功,写入日志中..
    13. payLog(verifySignatureMap);
    14. String analysisCode = verifySignatureMap.get("analysisCode");
    15. if (!analysisCode.equals("200")) {
    16. return resultFail();
    17. }
    18. // 3. 执行回调异步相关逻辑
    19. return asyncService(verifySignatureMap);
    20. }
    21. /**
    22. * 支付回调验证参数
    23. *
    24. * @return
    25. */
    26. protected abstract Map<String, String> verifySignature();
    27. /**
    28. * 使用多线程异步写入日志
    29. *
    30. * @param verifySignatureMap
    31. */
    32. @Async
    33. private void payLog(Map<String, String> verifySignatureMap) {
    34. log.info(">>>>>>>>>>第二步 写入payLog........");
    35. }
    36. /**
    37. * 每个子类需要实现 实现业务解析操作
    38. *
    39. * @return
    40. */
    41. protected abstract String asyncService(Map<String, String> verifySignatureMap);
    42. /**
    43. * 异步返回结果..
    44. *
    45. * @return
    46. */
    47. protected abstract String resultSuccess();
    48. /**
    49. * 异步返回失败
    50. *
    51. * @return
    52. */
    53. protected abstract String resultFail();
    54. }

    具体实现:

    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", "充值蚂蚁课堂永久会员");
    11. // 支付状态为1表示为成功....
    12. verifySignature.put("aliPayMentStatus", "1");
    13. verifySignature.put("aliPayOrderNumber", "201910101011");
    14. // 解析报文是否成功 200 为成功..
    15. verifySignature.put("analysisCode", "200");
    16. return verifySignature;
    17. }
    18. @Override
    19. protected String asyncService(Map<String, String> verifySignatureMap) {
    20. log.info(">>>>>第三步asyncService()verifySignatureMap:{}", verifySignatureMap);
    21. String paymentStatus = verifySignatureMap.get("aliPayMentStatus");
    22. if (paymentStatus.equals("1")) {
    23. String aliPayOrderNumber = verifySignatureMap.get("aliPayOrderNumber");
    24. log.info(">>>>orderNumber:{aliPayOrderNumber},已经支付成功 修改订单状态为已经支付...");
    25. }
    26. return resultSuccess();
    27. }
    28. @Override
    29. protected String resultSuccess() {
    30. return "ok";
    31. }
    32. }
    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", "充值蚂蚁课堂永久会员");
    11. // 支付状态为1表示为成功....
    12. verifySignature.put("paymentStatus", "1");
    13. verifySignature.put("orderNumber", "201910101011");
    14. // 解析报文是否成功 200 为成功..
    15. verifySignature.put("analysisCode", "200");
    16. return verifySignature;
    17. }
    18. @Override
    19. protected String asyncService(Map<String, String> verifySignatureMap) {
    20. log.info(">>>>>第三步asyncService()verifySignatureMap:{}", verifySignatureMap);
    21. String paymentStatus = verifySignatureMap.get("paymentStatus");
    22. if (paymentStatus.equals("1")) {
    23. String orderNumber = verifySignatureMap.get("orderNumber");
    24. log.info(">>>>orderNumber:{orderNumber},已经支付成功 修改订单状态为已经支付...");
    25. }
    26. return resultSuccess();
    27. }
    28. @Override
    29. protected String resultSuccess() {
    30. return "success";
    31. }
    32. }

    工厂模式获取模板

    1. public class TemplateFactory {
    2. public static AbstractPayCallbackTemplate getPayCallbackTemplate(String templateId) {
    3. AbstractPayCallbackTemplate payCallbackTemplate = (AbstractPayCallbackTemplate) SpringUtils.getBean(templateId);
    4. return payCallbackTemplate;
    5. }
    6. }

    如何调用:

    1. @RestController
    2. public class TemplateController {
    3. @RequestMapping("/asyncCallBack")
    4. public String asyncCallBack(String templateId) {
    5. AbstractPayCallbackTemplate payCallbackTemplate = TemplateFactory.getPayCallbackTemplate(templateId);
    6. return payCallbackTemplate.asyncCallBack();
    7. }
    8. }