模版方法模式

简介

在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。

使用场景:

  • Servlet生命周期方法

  • Spring的JdbcTemplate

  • 框架的生命周期钩子

  • 通用的业务流程

实现要点:

  • 模板方法定义算法骨架

  • 抽象方法由子类实现

  • 钩子方法提供可选扩展

UML

代码示例

  1. 算法的骨架

/**
 * @author dcx
 * 工人的超类
 * <p>
 * 模板方法模式中的三类角色
 * 1、具体方法(Concrete Method)
 * 2、抽象方法(Abstract Method)
 * 3、钩子方法(Hook Method)
 * <p>
 * 三类角色的关联
 * 在模板方法模式中,首先父类会定义一个算法的框架,即实现算法所必须的所有方法。
 * <p>
 * 其中,具有共性的代码放在父类的具体方法中。
 * <p>
 * 各个子类特殊性的代码放在子类的具体方法中。但是父类中需要有对应抽象方法声明。
 * 钩子方法可以让子类决定是否对算法的不同点进行挂钩。
 * @create 2025-09-16 09:52
 **/
public abstract class Worker {

    protected String name;

    public Worker(String name) {
        this.name = name;
    }

    /**
     * 具体方法
     */
    public final void workOneDay() {
        System.out.println(name + " workOneDay -----------------work start----------------");
        enterCompany();
        computerOn();
        work();
        computerOff();
        exitCompany();
        System.out.println(name + " workOneDay -----------------work end----------------");
    }

    /**
     * 工作  抽象方法
     */
    public abstract void work();

    /**
     * 钩子方法
     */
    public boolean isNeedPrintDate() {
        return false;
    }

    private void exitCompany() {
        if (isNeedPrintDate()) {
            System.out.println("exitCompany ---" + new Date() + "--->");
        }
        System.out.println("exitCompany" + name + "---离开公司");
    }


    private void computerOn() {
        System.out.println("computerOn ---打开电脑");
    }

    private void computerOff() {
        System.out.println("computerOff ---关闭电脑");
    }

    private void enterCompany() {
        System.out.println("enterCompany ---进入公司");
    }
}
  1. 子类实现

public class CTOWorker extends Worker {
    public CTOWorker(String name) {
        super(name);
    }

    @Override
    public void work() {
        System.out.println("--work ---" + name + ", 开会 - 出API - 检查进度");
    }
}
public class HRWorker extends Worker {
    public HRWorker(String name) {
        super(name);
    }

    @Override
    public void work() {
        System.out.println("--work ---" + name + ", 看简历 - 打电话 - 接电话");
    }
}
public class ITWorker extends Worker {
    public ITWorker(String name) {
        super(name);
    }

    @Override
    public boolean isNeedPrintDate() {
        return true;
    }

    @Override
    public void work() {
        System.out.println("--work ---" + name + ", 写程序 - 测bug - 修复bug");
    }
}
public class OtherWorker extends Worker {
    public OtherWorker(String name) {
        super(name);
    }

    @Override
    public void work() {
        System.out.println("--work ---" + name + ",打LOL...");
    }
}
public class QAWorker extends Worker {
    public QAWorker(String name) {
        super(name);
    }

    @Override
    public void work() {
        System.out.println("--work ---" + name + ", 写测试用例 - 提交Bug - 复查Bug");
    }
}
  1. 使用方式

public class Test {
    public static void main(String[] args) {
        CTOWorker cto = new CTOWorker("CTO");
        cto.workOneDay();

        HRWorker hr = new HRWorker("HR");
        hr.workOneDay();

        ITWorker it = new ITWorker("IT");
        it.workOneDay();

        OtherWorker otherWorker = new OtherWorker("其他人员");
        otherWorker.workOneDay();

        QAWorker qa = new QAWorker("QA");
        qa.workOneDay();
    }
}

Last updated

Was this helpful?