Java 编程之模板方法模式

引言

本文用一杯茶咖,让你喝懂模板方法模式设计思想

☕ "程序员不止写代码,也懂泡茶和冲咖啡。"

模板方法模式------把固定的流程封装在抽象类中 ,把可变的步骤交给子类决定。本文通过生活化例子+代码一一对应讲透它!


一、模板方法模式定义

模板方法模式(Template Method Pattern)是一种行为型设计模式 ,用于定义一个操作中的算法骨架 ,而将一些步骤的实现延迟到子类中

通俗地说:

父类定流程,子类补细节。

这使得子类在不改变整体算法结构的前提下,能够重新定义某些步骤的实现方式


二、类比用例

在生活中,泡茶与冲咖啡为例来理解这一设计模式。

泡茶与冲咖啡的流程都很像:

  1. 烧开水
  2. 冲泡
  3. 倒入杯中
  4. 如果愿意,可以加入佐料(如柠檬片、糖、牛奶等)

于是,我们可以把这套流程抽象为一个"饮品冲泡模板",具体细节(茶叶 or 咖啡粉,是否加佐料)由子类决定。


三、模板方法模式结构

plantuml 复制代码
@startuml
abstract class CaffeineBeverage {
    +prepareRecipe()
    -boilWater()
    -pourInCup()
    +brew() : abstract
    +addCondiments() : abstract
}

class Tea extends CaffeineBeverage
class Coffee extends CaffeineBeverage

CaffeineBeverage <|-- Tea
CaffeineBeverage <|-- Coffee
@enduml

四、代码实现:把生活变代码

4.1. 饮品冲泡模板(抽象类)

java 复制代码
public abstract class CaffeineBeverage {

    // 模板方法,不可重写
    public final void prepareRecipe() {
        boilWater();
        brew();                 // 由子类实现
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();    // 由子类实现
        }
    }

    void boilWater() {
        System.out.println("把水煮沸");
    }

    void pourInCup() {
        System.out.println("把饮料倒进杯子");
    }

    // 钩子方法:子类可以选择是否重写
    boolean customerWantsCondiments() {
        return true;
    }

    abstract void brew();           // 冲泡方式不同
    abstract void addCondiments();  // 添加佐料方式不同
}

4.2. 茶类实现

java 复制代码
public class Tea extends CaffeineBeverage {

    @Override
    void brew() {
        System.out.println("用热水浸泡茶叶");
    }

    @Override
    void addCondiments() {
        System.out.println("加点柠檬片");
    }

    @Override
    boolean customerWantsCondiments() {
        return true; // 或根据用户输入来动态判断
    }
}

4.3. 咖啡类实现

java 复制代码
public class Coffee extends CaffeineBeverage {

    @Override
    void brew() {
        System.out.println("用热水冲泡咖啡粉");
    }

    @Override
    void addCondiments() {
        System.out.println("加糖和牛奶");
    }

    @Override
    boolean customerWantsCondiments() {
        return false; // 咖啡师决定不加
    }
}

4.4. 客户端享用

java 复制代码
public class BeverageTestDrive {
    public static void main(String[] args) {
        System.out.println("---------- 泡一杯茶 ----------");
        CaffeineBeverage tea = new Tea();
        tea.prepareRecipe();

        System.out.println("\n---------- 冲一杯咖啡 ----------");
        CaffeineBeverage coffee = new Coffee();
        coffee.prepareRecipe();
    }
}

输出结果:

复制代码
---------- 泡一杯茶 ----------
把水煮沸
用热水浸泡茶叶
把饮料倒进杯子
加点柠檬片

---------- 冲一杯咖啡 ----------
把水煮沸
用热水冲泡咖啡粉
把饮料倒进杯子

五、关键点分析

步骤 属于抽象类 属于子类 是否可扩展
boilWater()
brew()
addCondiments()
prepareRecipe() ✅(final)
customerWantsCondiments() ✅(钩子) ✅(可重写) ✅(灵活)

六、优缺点总结

模板方法模式:

流程写死在抽象类 ,把差异开放给子类

这样就能稳定结构 ,又自由扩展

优点

  • 提高代码复用性:公共流程只写一次,子类只专注差异化实现。
  • 提高扩展性:子类可按需定制部分步骤。
  • 实现**"开闭原则"**:结构稳定,细节可变。

缺点

  • 增加了类的数量(每种实现都要新建类)
  • 对类结构理解有一定要求,不适合流程极度不确定的场景

七、应用场景

模板方法常见于以下场景:

  • 框架设计 :如 Servlet 的 doGet() / doPost()service() 中被调用。
  • 数据处理流程:读取文件 → 解析 → 验证 → 存储。
  • 游戏或AI算法中的行为模板。

八、附加建议:代码增强思路

  • 增加用户交互 Scanner 控制是否加佐料
  • Logger 代替 System.out.println
  • 封装为"饮品工厂"模式组合使用

九、参考

《23种设计模式概览》

相关推荐
程序喵大人20 分钟前
【C++进阶】STL算法与函数对象 - 09 函数对象保存状态并复用规则
开发语言·c++·算法·stl·函数对象
程序员黑豆4 小时前
Java包装类:基本类型与对象的桥梁
java·前端·ai编程
hsjiasb6 小时前
FreeRTOS学习(二十七)——任务栈与栈溢出检测
开发语言·stm32·学习·学习笔记·freertos
丰锋ff7 小时前
3.1 Qt事件之事件处理器
开发语言·qt
多弗朗皮卡丘7 小时前
C语言梦开始的地方7:函数
c语言·开发语言
mldong7 小时前
"applicant" 契约:退回发起人的闭环设计
java·架构
月华路8 小时前
G1 垃圾回收:脏卡队列、记忆集与并发精化线程机制
java·开发语言
gugucoding8 小时前
47. 【Java】Java内存模型(JMM)与可见性
java·开发语言
m0_380743878 小时前
从零调用 Claude 教程
开发语言·python·node.js
起床学FPGA9 小时前
AI回答问题之后,会自动跳到最下面的问题
开发语言·javascript·ecmascript