源码下载
https://logaaaaa.oss-cn-beijing.aliyuncs.com/com.gtf-1654655556486.zip

什么是模版方法

1.定义了一个操作中的算法的骨架,而将部分步骤的实现在子类中完成。
模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
2.模板方法模式是所有模式中最为常见的几个模式之一,是基于继承的代码复用的基本技术,没有关联关系。 因此,在模板方法模式的类结构图中,只有继承关系。

核心设计要点:
AbstractClass : 抽象类,定义并实现一个模板方法。这个模板方法定义了算法的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类去实现
ConcreteClass : 实现实现父类所定义的一个或多个抽象方法。

模版方法优缺点

1.)优点
模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。子类实现算法的某些细节,有助于算法的扩展。通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。
2.)缺点
每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。
3.)适用场景
在某些类的算法中,用了相同的方法,造成代码的重复。控制子类扩展,子类必须遵守算法规则。

模版方法应用场景

1.比如聚合支付平台中系统回调代码重构
2.Servlet 请求

模版方法+工厂实现

定位抽象角色模版

package com.gtf.template;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;

import java.util.Map;

/**
 * 抽象角色模版
 */
@Slf4j
public abstract class AbstractPayCallTemplate  {

    /**
     * 共同行为骨架
     * @return
     */
    public String asyncCall(){
        //1。验证参数和签名
        Map<String,String> verifySignature=verifySignature();
        //2.日志收集
        payLog(verifySignature);
        if (!verifySignature.get("analysisCode").equals("200")) {
            return resultFail();
        }
        //3.更改数据库状态,同时返回不同的支付结果。
         return  asyncService(verifySignature);
    }

    /**
     * 返回失败方法
     * @return
     */
    protected abstract String resultFail();

    /**
     * 使用多线程异步写入日志
     * @param verifySignature
     */
    @Async
    public void payLog(Map<String, String> verifySignature) {
        System.out.println("写入数据库中");
    }

    /**
     * 验证参数
     * @return
     */
    protected abstract Map<String, String> verifySignature();

    /**
     * 执行订单修改,返回不同的结果
     * @param verifySignature
     * @return
     */
    protected abstract String asyncService(Map<String, String> verifySignature);

    /**
     * 返回成功
     * @return
     */
    protected abstract String resultSuccess();
}

定义具体实现1

package com.gtf.template.impl;

import com.gtf.template.AbstractPayCallTemplate;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
@Slf4j
public class AliPayCallbackTemplate extends AbstractPayCallTemplate {
    @Override
    protected String resultFail() {
        return "fail";
    }

    @Override
    protected Map<String, String> verifySignature() {
        //>>>>假设一下为银联回调报文>>>>>>>>>>>>>>>>
        log.info(">>>>>第一步 解析支付宝据报文.....verifySignature()");
        Map<String, String> verifySignature = new HashMap<>();
        verifySignature.put("price", "1399");
        verifySignature.put("orderDes", "充值永久会员");
        // 支付状态为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},已经支付成功 修改订单状态为已经支付...");
        }
        return resultSuccess();
    }

    @Override
    protected String resultSuccess() {
        return "success";
    }
}

定义具体实现2

package com.gtf.template.impl;

import com.gtf.template.AbstractPayCallTemplate;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
@Slf4j
public class UnionPayCallbackTemplate extends AbstractPayCallTemplate {
    @Override
    protected String resultFail() {
        return "fail";
    }

    @Override
    protected Map<String, String> verifySignature() {
        //>>>>假设一下为银联回调报文>>>>>>>>>>>>>>>>
        log.info(">>>>>第一步 UnionPayCallbackTemplate.....verifySignature()");
        Map<String, String> verifySignature = new HashMap<>();
        verifySignature.put("price", "1399");
        verifySignature.put("orderDes", "充值永久会员");
        // 支付状态为1表示为成功....56780-
        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(">>>>>  UnionPayCallbackTemplate 第三步asyncService()verifySignatureMap:{}", verifySignature);
        String paymentStatus = verifySignature.get("aliPayMentStatus");
        if (paymentStatus.equals("1")) {
            String aliPayOrderNumber = verifySignature.get("aliPayOrderNumber");
            log.info(">>>>orderNumber:{UnionPayCallbackTemplate},已经支付成功 修改订单状态为已经支付...");
        }
        return resultSuccess();
    }

    @Override
    protected String resultSuccess() {
        return "success";
    }
}

定义工厂

package com.gtf.factory;

import com.gtf.template.AbstractPayCallTemplate;
import com.gtf.utils.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class temlateFactory {
    /**
     * 使用工厂模式获取模版
     * @param temlateId
     * @return
     */
    public static AbstractPayCallTemplate getPayCallTemplate(String temlateId) {
        AbstractPayCallTemplate bean = (AbstractPayCallTemplate)SpringUtils.getBean(temlateId);
        return bean;
    }
}

策略模式 与模版方法模式的区别

策略模式 不同的骨架(多重if)
模版方法 相同的骨架

servlet 模版方法

doget
dopost