小易说IT 小易说IT

Java模板方法(Template Method)示例代码

核心思想:定义一个算法骨架,把部分步骤延迟到子类实现。父类固定流程,子类重写可变步骤,不改变整体执行顺序。

  • 抽象父类:提供final模板方法,规定整体流程;定义抽象方法交给子类实现;可提供钩子方法。

  • 具体子类:实现抽象步骤,自定义业务逻辑。

  • 模板方法用final,防止子类重写打乱流程。

Java 完整示例

/**
 * 抽象模板类:定义算法骨架
 */
public abstract class AbstractCook {

    // 模板方法:final禁止子类重写,固定执行流程
    public final void cookProcess() {
        pourOil();
        heatOil();
        putVegetable();
        putSauce();
        fry();
        hookPrintFinish();
    }

    // 通用步骤:父类实现,所有子类共用
    private void pourOil() {
        System.out.println("1. 倒入食用油");
    }

    private void heatOil() {
        System.out.println("2. 加热食用油");
    }

    // 可变步骤:抽象,子类必须实现
    protected abstract void putVegetable();

    protected abstract void putSauce();

    private void fry() {
        System.out.println("4. 大火翻炒");
    }

    // 钩子方法:可选重写,默认空实现,子类可选择性覆盖
    protected void hookPrintFinish() {
    }
}

/**
 * 具体子类:炒西红柿鸡蛋
 */
class CookTomatoEgg extends AbstractCook {
    @Override
    protected void putVegetable() {
        System.out.println("3. 放入西红柿和鸡蛋");
    }

    @Override
    protected void putSauce() {
        System.out.println("3.1 加入盐、白糖调味");
    }

    // 重写钩子方法
    @Override
    protected void hookPrintFinish() {
        System.out.println("✅ 西红柿炒鸡蛋完成!");
    }
}

/**
 * 具体子类:炒青菜
 */
class CookGreenVegetable extends AbstractCook {
    @Override
    protected void putVegetable() {
        System.out.println("3. 放入青菜");
    }

    @Override
    protected void putSauce() {
        System.out.println("3.1 加入盐、少许生抽");
    }

    @Override
    protected void hookPrintFinish() {
        System.out.println("✅ 清炒青菜完成!");
    }
}

// 测试客户端
class Client {
    public static void main(String[] args) {
        AbstractCook dish1 = new CookTomatoEgg();
        dish1.cookProcess();

        System.out.println("----------------------");

        AbstractCook dish2 = new CookGreenVegetable();
        dish2.cookProcess();
    }
}

输出结果

1. 倒入食用油
2. 加热食用油
3. 放入西红柿和鸡蛋
3.1 加入盐、白糖调味
4. 大火翻炒
✅ 西红柿炒鸡蛋完成!
----------------------
1. 倒入食用油
2. 加热食用油
3. 放入青菜
3.1 加入盐、少许生抽
4. 大火翻炒
✅ 清炒青菜完成!

UML 逻辑说明

  1. AbstractCook:抽象模板,cookProcess()模板方法,定义执行顺序;

  2. pourOil/heatOil/fry:公共固定逻辑,父类私有实现;

  3. putVegetable/putSauce:抽象原语操作,子类实现;

  4. hookPrintFinish钩子方法,空实现,子类按需重写;

  5. final修饰模板方法,防止子类篡改整体流程。

实际 JDK 中的模板方法例子

java.io.InputStream#read(byte b[], int off, int len)

  • 该方法是模板方法,内部调用抽象read(),由子类 FileInputStream 等实现底层读取。

优缺点

✅ 优点

  1. 复用公共代码,算法骨架封装在父类;

  2. 子类扩展可变部分,符合开闭原则;

  3. 流程集中控制,子类不能随意修改步骤顺序。

❌ 缺点

  1. 每个不同实现都要新增子类,类数量膨胀;

  2. 继承耦合,父类改动会影响全部子类。

模板方法基于继承;策略模式基于组合,二者经常拿来对比。


本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。

原文链接 https://www.yijunzhao.cc/archives/java-template-method-pattern-example-code

欢迎访问 https://www.yijunzhao.cc/

https://www.yijunzhao.cc/