核心思想:定义一个算法骨架,把部分步骤延迟到子类实现。父类固定流程,子类重写可变步骤,不改变整体执行顺序。
抽象父类:提供
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 逻辑说明
AbstractCook:抽象模板,cookProcess()是模板方法,定义执行顺序;pourOil/heatOil/fry:公共固定逻辑,父类私有实现;putVegetable/putSauce:抽象原语操作,子类实现;hookPrintFinish:钩子方法,空实现,子类按需重写;final修饰模板方法,防止子类篡改整体流程。
实际 JDK 中的模板方法例子
java.io.InputStream#read(byte b[], int off, int len)
该方法是模板方法,内部调用抽象
read(),由子类 FileInputStream 等实现底层读取。
优缺点
✅ 优点
复用公共代码,算法骨架封装在父类;
子类扩展可变部分,符合开闭原则;
流程集中控制,子类不能随意修改步骤顺序。
❌ 缺点
每个不同实现都要新增子类,类数量膨胀;
继承耦合,父类改动会影响全部子类。
模板方法基于继承;策略模式基于组合,二者经常拿来对比。
本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。
原文链接
欢迎访问