Spring中使用模板方法模式

接上一篇文章末尾提出的扩展点,本次进行实现。上文链接:Spring项目中使用策略模式+工厂模式

改动

  1. 以下是之前的PayService接口,之前为了举例,只是简单写了两个方法。
/**
 * PayService
 *
 * @author ZXP
 * @date 2021/12/4 21:23
 */
public interface PayService {

    /**
     * 支持的支付类型
     *
     * @return
     */
    PayEnum getPayType();

    /**
     * 具体的支付逻辑
     *
     * @param obj
     */
    void pay(Object obj);
}
  1. 本次演示模板方法模式,再添加如下的业务方法,sign() 为签名方法,微信支付和支付宝支付都需要先进行签名再请求接口,每个实现类签名方法略有不同,所以交由具体实现类实现,createOrder() 为创建订单方法,doPay() 为支付主方法,业务处主要调用的方法。
/**
 * PayService
 *
 * @author ZXP
 * @date 2021/12/4 21:23
 */
public interface PayService {

    /**
     * 支持的支付类型
     *
     * @return
     */
    PayEnum getPayType();

    /**
     * 签名
     *
     * @param obj
     * @return
     */
    String sign(Object obj);

    /**
     * 创建订单
     *
     * @param obj
     */
    void createOrder(Object obj);

    /**
     * 具体的支付逻辑
     *
     * @param obj
     */
    void pay(Object obj);

    /**
     * 支付主方法
     *
     * @param obj
     */
    void doPay(Object obj);
}
  1. 增加抽象实现类AbstractPayServiceImpl,该类位于PayService接口与AliPayServiceImpl等具体实现类中间,为 createOrder() 等逻辑相同的方法提供默认实现,并在 doPay() 主方法中将各个方法调用逻辑组织起来。
@Service
public abstract class AbstractPayServiceImpl implements PayService {

    @Override
    public void createOrder(Object obj) {
        // 创建订单的逻辑
        System.out.println(String.format("创建%s类型的订单", getPayType().getEn()));
    }

    /**
     * 主方法,里边组织各个方法的调用逻辑
     *
     * @param obj
     */
    @Override
    public void doPay(Object obj) {

        // 1.签名,各个支付商签名方式可能不一样,所以交由各个子类实现
        sign(obj);

        // 2.创建订单,创建订单的逻辑大致一致,可以在抽象类中实现,如有不一致的可再子类中重写
        // 默认调用抽象类中实现的
        createOrder(obj);

        // 3.支付的逻辑,各个支付商签名方式可能不一样,所以交由各个子类实现
        pay(obj);
    }
}
  1. 修改具体实现类继承抽象类,并重写抽象方法,由于createOrder() 在抽象类中已提供默认实现,所以具体子类中不需要重写,如果默认实现满足不了某个子类,则子类可以进行重写。
/**
 * 支付宝支付处理类
 *
 * @author ZXP
 * @date 2021/12/4 21:29
 */
@Service
public class AliPayServiceImpl extends AbstractPayServiceImpl {

    @Override
    public PayEnum getPayType() {
        return PayEnum.ALIPAY;
    }

    /**
     * 支付宝支付的签名逻辑
     *
     * @param obj
     * @return
     */
    @Override
    public String sign(Object obj) {
        return "testAliPaySign";
    }

    @Override
    public void pay(Object obj) {
        // 支付宝支付的逻辑
        System.out.println("使用了支付宝支付");
    }
}
/**
 * 微信支付处理类
 *
 * @author ZXP
 * @date 2021/12/4 21:28
 */
@Service
public class WxPayServiceImpl extends AbstractPayServiceImpl {

    @Override
    public PayEnum getPayType() {
        return PayEnum.WX;
    }

    /**
     * 微信支付的签名逻辑
     *
     * @param obj
     * @return
     */
    @Override
    public String sign(Object obj) {
        return "testWxSign";
    }

    @Override
    public void pay(Object obj) {
        // wx支付逻辑
        System.out.println("使用了微信支付");
    }
}

使用演示

@Test
public void testPay() {
    // 调用doPay()支付主方法
    PayServiceFactory.get(PayEnum.WX).doPay(new Object());
    PayServiceFactory.get(PayEnum.ALIPAY).doPay(new Object());
}

执行结果

执行结果

总结

引入模板方法模式将支付主逻辑在doPay() 主方法中进行实现,其中各个子方法的实现可能有相同也可能有不同,根据需求在AbstractPayServiceImpl中来选择是否重写,如果未重写则子类必须重写;已重写的方法,子类可以根据默认方法是否满足自身需求来选择是否需要重写,从而使得代码耦合度降低,并且可读性也有所提升,每个类的职责单一,不至于太过复杂。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值