Java设计模式之模板方法模式

概念

模板方法模式是一种行为型设计模式,它定义了一个算法的骨架,允许子类在不改变算法结构的情况下重定义某些步骤。父类通过模板方法控制流程,子类通过实现抽象方法填充细节。

作用

**1.代码复用:**公共逻辑抽取到父类,避免重复代码。

**2.扩展性:**子类只需关注差异部分,符合开闭原则。

**3.流程控制:**父类固定核心流程,防止子类破坏执行顺序。

场景

1.多个类具有相似流程但部分步骤不同(如数据解析、文件处理)。

2.需要固定核心算法流程,允许子类扩展特定步骤。

3.框架设计(如Spring的JdbcTemplate)。

举例(饮料制作)

复制代码
// 饮料类
abstract class Beverage {
    // 准备食谱:模板方法 (final防止子类覆盖)
    public final void prepareRecipe() {
        // 烧开水
        boilWater();
        // 泡
        brew();
        // 倒入杯子
        pourInCup();
        // 是否加入调味剂
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }

    // 固定步骤:烧开水
    private void boilWater() {
        System.out.println("烧开水");
    }
    // 固定步骤:倒入杯子
    private void pourInCup() {
        System.out.println("倒入杯子");
    }

    // 抽象方法(必须实现)
    abstract void brew();
    abstract void addCondiments();

    // 钩子方法(可选覆盖)
    boolean customerWantsCondiments() {
        return true;
    }
}

class Coffee extends Beverage {
    @Override
    void brew() {
        System.out.println("冲泡咖啡粉");
    }

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

    @Override
    boolean customerWantsCondiments() {
        return false; // 示例:咖啡不要调料
    }
}

class Tea extends Beverage {
    @Override
    void brew() {
        System.out.println("浸泡茶叶");
    }

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

优点和缺点

|----------------|------------------|
| 优点 | 缺点 |
| 代码复用率高 | 增加类数量(每个差异需一个子类) |
| 扩展性强(新增子类即可) | 父类修改可能影响所有子类 |
| 反向控制结构(父类调用子类) | 过度继承可能导致系统复杂 |

不使用模板方法的实现

复制代码
class CoffeeWithoutPattern {
    public void makeCoffee() {
        System.out.println("烧开水");
        System.out.println("冲泡咖啡粉");
        System.out.println("倒入杯子");
        System.out.println("加糖和牛奶"); // 重复代码
    }
}

class TeaWithoutPattern {
    public void makeTea() {
        System.out.println("烧开水");       // 重复代码
        System.out.println("浸泡茶叶");
        System.out.println("倒入杯子");    // 重复代码
        System.out.println("加柠檬");
    }
}

存在的问题

**1.重复代码:**烧开水、倒杯子的代码重复。

**2.维护困难:**修改流程需改动所有类。

**3.无法强制统一流程:**子类可能遗漏步骤或改变顺序。

|------|-----|-----|------|------|
| 方案 | 代码量 | 扩展性 | 维护成本 | 流程控制 |
| 模板方法 | 少 | 高 | 低 | 严格统一 |
| 传统实现 | 多 | 低 | 高 | 自由松散 |

设计启示:当遇到多个相似流程的类时,优先使用模板方法模式消除重复代码,尤其适合需要严格流程控制的场景。

相关推荐
IronMurphy4 小时前
SSM拷打第二讲!!!
java·spring·mybatis
小江的记录本4 小时前
【JVM虚拟机】类加载机制:类加载全流程:加载→验证→准备→解析→初始化(附《思维导图》+《面试高频考点清单》)
java·jvm·spring boot·算法·安全·spring·面试
千纸鹤の脉搏4 小时前
多线程的初步了解---进程与线程
java·开发语言·学习·线程
许彰午4 小时前
状态模式实战——Row对象的状态机
java·ui·状态模式
搬石头的马农5 小时前
Claude Code SpringBoot开发:从0到1搭建企业级项目的6个核心Skill
java·人工智能·spring boot·后端·ai编程
西安邮电大学5 小时前
Redis为什么快?
java·redis·后端·其他·面试
折哥的程序人生 · 物流技术专研5 小时前
《Java 100 天进阶之路》第39篇:Java泛型方法的定义和使用
java·开发语言·后端·面试·求职招聘
土狗TuGou5 小时前
SQL内功笔记 · 第6篇:窗口函数的使用ROW_NUMBER等
java·数据库·后端·sql·mysql
Chase_______5 小时前
【Java基础核心知识点全解·09】Java 内存布局与垃圾回收详解:栈、堆、栈帧、GC Roots 与对象回收
java·开发语言
武子康5 小时前
Java-11 深入浅出 MyBatis 一级缓存详解:从原理到失效场景 Executor
java·后端