java23种设计模式-模板方法模式
模板方法模式(Template Method Pattern)学习笔记
1. 模式定义
行为型设计模式,在抽象类中定义算法的骨架,将某些步骤延迟到子类实现。允许子类在不改变算法结构的情况下重新定义特定步骤。
2. 适用场景
✅ 存在多个相似算法流程但部分步骤不同的场景
✅ 需要固定算法执行顺序的场景
✅ 需要扩展算法特定步骤的场景
✅ 框架设计(父类控制流程,子类实现具体逻辑)
✅ 需要消除重复代码(多个子类有相同结构)
3. 模式结构
4. 核心角色
角色 | 说明 |
---|---|
AbstractClass | 抽象类,定义模板方法和算法步骤(抽象方法/具体方法/钩子方法) |
ConcreteClass | 具体子类,实现抽象步骤,可选覆盖默认实现或钩子方法 |
5. 代码示例
5.1 饮料制作示例
// 抽象类
abstract class BeverageTemplate {
// 模板方法(final防止子类覆盖)
public final void prepareBeverage() {
boilWater();
brew();
pourInCup();
if (needCondiments()) {
addCondiments();
}
}
// 通用步骤实现
private void boilWater() {
System.out.println("煮沸水");
}
private void pourInCup() {
System.out.println("倒入杯子");
}
// 抽象方法(必须实现)
protected abstract void brew();
protected abstract void addCondiments();
// 钩子方法(可选覆盖)
protected boolean needCondiments() {
return true;
}
}
// 具体子类
class Coffee extends BeverageTemplate {
@Override
protected void brew() {
System.out.println("冲泡咖啡粉");
}
@Override
protected void addCondiments() {
System.out.println("加入糖和牛奶");
}
@Override
protected boolean needCondiments() {
return false; // 示例:咖啡不要调料
}
}
class Tea extends BeverageTemplate {
@Override
protected void brew() {
System.out.println("浸泡茶叶");
}
@Override
protected void addCondiments() {
System.out.println("加入柠檬");
}
}
// 客户端
public class Client {
public static void main(String[] args) {
BeverageTemplate coffee = new Coffee();
coffee.prepareBeverage();
System.out.println("\n===============\n");
BeverageTemplate tea = new Tea();
tea.prepareBeverage();
}
}
6. 模式变种
-
钩子方法(Hook Methods):
在抽象类中提供空实现或默认返回true的方法,子类可选择覆盖来控制流程protected boolean validate() { return true; // 默认验证通过 }
-
模板方法重载:
提供多个版本的模板方法应对不同场景public final void process(boolean isQuickMode) { if (isQuickMode) { step1(); step3(); } else { templateMethod(); } }
7. 优缺点分析
✔️ 优点:
- 封装不变部分,扩展可变部分
- 父类控制算法结构,子类专注细节实现
- 代码复用率高,减少重复代码
- 符合开闭原则(通过扩展增加新实现)
❌ 缺点:
- 每增加一个实现需要新建子类,可能增加系统复杂度
- 父类修改可能影响所有子类
- 继承关系限制了灵活性(可通过组合+策略模式优化)
8. 相关模式对比
模式 | 目的 | 关键区别 |
---|---|---|
策略模式 | 封装算法族 | 使用组合实现,更灵活 |
工厂方法模式 | 创建对象 | 属于创建型模式 |
建造者模式 | 分步构建对象 | 关注对象创建过程 |
命令模式 | 封装请求 | 将操作封装为对象 |
9. 实际应用案例
- Java Servlet的
service()
方法 - Spring框架的
JdbcTemplate
- Hibernate的
HibernateTemplate
- Java集合框架的
AbstractList
/AbstractSet
- AWT的
WindowAdapter
(适配器模式+模板方法) - Junit的
TestCase
生命周期方法(setUp()/tearDown())
10. 最佳实践建议
- 模板方法声明为final:防止子类重写算法结构
- 合理使用钩子方法:在关键扩展点提供可控覆盖
- 控制抽象方法数量:避免过多步骤导致子类实现困难
- 结合其他模式使用:
- 与工厂方法模式结合创建步骤所需对象
- 与策略模式结合替换特定算法步骤
- 优先使用组合:当需要突破单继承限制时,改用策略模式
- 文档注释:明确说明每个步骤的作用和调用顺序
11. 扩展应用示例(Spring JdbcTemplate)
public abstract class JdbcTemplate {
public final Object execute(String sql) {
Connection con = null;
try {
con = getConnection();
PreparedStatement ps = con.prepareStatement(sql);
setParameters(ps); // 抽象方法
ps.execute();
return handleResult(ps); // 抽象方法
} finally {
releaseConnection(con);
}
}
protected abstract void setParameters(PreparedStatement ps) throws SQLException;
protected abstract Object handleResult(Statement stmt) throws SQLException;
// ...其他通用方法...
}
// 使用示例
new JdbcTemplate() {
@Override
protected void setParameters(PreparedStatement ps) {
ps.setString(1, "paramValue");
}
@Override
protected Object handleResult(Statement stmt) {
return ((PreparedStatement)stmt).getResultSet();
}
}.execute("SELECT * FROM table WHERE col = ?");
📐 设计原则体现:
- 好莱坞原则(Don’t call us, we’ll call you):父类控制流程,子类只需实现特定步骤
- 开闭原则(OCP):通过扩展子类增加新实现,无需修改现有代码
- 单一职责原则(SRP):将算法步骤拆分到不同方法
通过模板方法模式,可以有效管理复杂流程的标准化实现,特别适合框架开发和企业级应用中的通用流程控制场景。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!