模板方法模式

介绍

**定义:**模板方法模式是一种基于继承的代码复用技术, 其结构只存在于父类和子类的继承关系中. 主要作用是提高程序的复用性(所有子类都可以复用父类中提供的模板方法代码)和拓展性(通过提供拓展点的方式使用户在不修改源码的前提下, 基于拓展点功能定制).

UML

示例

java 复制代码
package com.sumlv.demo;

import com.sumlv.demo.templatemethod.AliPayTransfer;
import com.sumlv.demo.templatemethod.TransferTemplate;

import java.math.BigDecimal;

public class Main {

    public static void main(String[] args) {
        TransferTemplate template = new AliPayTransfer();
        template.handle("accountA", "accountB", new BigDecimal("1000.00"));
    }

}
java 复制代码
package com.sumlv.demo.templatemethod;

import java.math.BigDecimal;

/**
 * 转账模板(抽象模板)
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-20
 */
public abstract class TransferTemplate {

    /**
     * 模板方法, 定义了整个逻辑的执行流程
     */
    public void handle(String sourceAccount, String targetAccount, BigDecimal amount) {
        if (this.validate(sourceAccount, targetAccount, amount)) {
            try {
                this.deductMoney(sourceAccount, amount);
                BigDecimal serviceCharge = this.calculateServiceCharge(amount);
                this.increaseMoney(targetAccount, amount.subtract(serviceCharge));
            } catch (Exception e) {
                // 此处省略回滚逻辑
            }
        }
    }

    /**
     * 参数校验, 对于确定的逻辑可以直接在父类中实现
     */
    protected boolean validate(String sourceAccount, String targetAccount, BigDecimal amount) {
        return sourceAccount != null && targetAccount != null && amount != null;
    }

    /**
     * 扣款, 对于确定的逻辑可以直接在父类中实现
     */
    protected void deductMoney(String targetAccount, BigDecimal amount) {
        // 此处省略转账方扣款逻辑.....
        System.out.println("账户:" + targetAccount + "扣款:" + amount + "元");
    }

    /**
     * 收款, 对于确定的逻辑可以直接在父类中实现
     */
    protected void increaseMoney(String targetAccount, BigDecimal amount) {
        // 此处省略收款方收款逻辑.....
        System.out.println("账户:" + targetAccount + "增加:" + amount + "元");
    }

    /**
     * 计算费率, 对于不确定的逻辑, 可以留到子类中实现
     */
    protected abstract BigDecimal calculateServiceCharge(BigDecimal amount);

}
java 复制代码
package com.sumlv.demo.templatemethod;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 微信转账
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-20
 */
public class WeChartTransfer extends TransferTemplate {

    private static final BigDecimal RATE = new BigDecimal("0.002");

    @Override
    protected BigDecimal calculateServiceCharge(BigDecimal amount) {
        BigDecimal serviceCharge = amount.multiply(RATE).setScale(2, RoundingMode.HALF_UP);
        System.out.println("使用微信支付, 扣除手续费:" + serviceCharge + "元");

        return serviceCharge;
    }

    /**
     * 可以通过重写父类方法的方式调整模板方法的执行步骤
     */
    @Override
    protected boolean validate(String sourceAccount, String targetAccount, BigDecimal amount) {
        return true;
    }
}
java 复制代码
package com.sumlv.demo.templatemethod;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 支付宝转账
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-20
 */
public class AliPayTransfer extends TransferTemplate {

    private static final BigDecimal RATE = new BigDecimal("0.001");

    @Override
    protected BigDecimal calculateServiceCharge(BigDecimal amount) {
        BigDecimal serviceCharge = amount.multiply(RATE).setScale(2, RoundingMode.HALF_UP);
        System.out.println("使用支付宝支付, 扣除手续费:" + serviceCharge + "元");

        return serviceCharge;
    }

}

总结

使用场景

  1. 当多个类有相同的逻辑和方法可以执行时;

  2. 当业务逻辑/算法高度类似, 仅有部分差异需要定制时.

优点:

1.父类定义执行步骤子类负责实现执行细节的模式可以让开发者避免编写冗余代码而更加专注于不同逻辑;

  1. 通过子类重写父类方法的模式可以灵活的调整执行步骤, 从而达到无需修改父类代码即可实现反向控制的目的.

  2. 新增/更换子类实现方便, 符合单一职责和开闭原则.

缺点:

  1. 针对不同实现需要编写不同子类, 导致子类个数增加, 系统更加庞大;

  2. 子类反向控制父类执行顺序的方式提高了代码阅读和问题排查的难度.

相关推荐
Aaron_dw3 天前
QT软件开发设计模式-模板方法模式
qt·设计模式·模板方法模式
我头发还没掉光~9 天前
富文本编辑器模板1
模板方法模式
清水白石00823 天前
模板方法模式全解析:用抽象基类定义算法骨架,让子类优雅填充细节
数据库·python·算法·模板方法模式
geovindu1 个月前
python: Template Method Pattern
开发语言·python·设计模式·模板方法模式
eqXUIrcRQM1 个月前
探索六自由度并联 Stewart Platform 平台的奇妙之旅
模板方法模式
Jzin1 个月前
翁牛特旗2025年玉米单产提升工程:全过程技术集成与项目执行方案
模板方法模式
Jzin1 个月前
翁牛特旗2025年玉米单产提升工程:第一标段核心技术参数对标与采购指南
模板方法模式
口袋物联1 个月前
模板方法模式在 C 语言中的应用(含 Linux 内核实例)
linux·c语言·模板方法模式
小温冲冲1 个月前
通俗且详细讲解模板方法模式
设计模式·模板方法模式