Java设计模式揭秘:深入理解模板方法模式
模板方法模式是Java中最容易理解却最常被忽视的设计模式之一。它用简单的继承机制解决了复杂流程的复用问题,是框架设计的基石。
一、什么是模板方法模式?
模板方法模式(Template Method Pattern)属于行为型设计模式 ,核心思想是:定义一个算法的骨架,将某些步骤延迟到子类中实现。该模式允许子类在不改变算法结构的情况下重新定义算法的某些特定步骤。
核心结构:
java
抽象类 {
// 模板方法(final防止子类覆盖)
final void 模板方法() {
步骤1();
步骤2();
步骤3();
}
// 抽象方法(子类必须实现)
abstract void 步骤2();
// 钩子方法(可选步骤)
void 步骤3() { /* 默认实现 */ }
}
二、模式结构解析
-
抽象模板类(Abstract Class)
- 定义算法骨架(模板方法)
- 声明抽象操作(子类需实现)
- 提供钩子方法(可选步骤)
-
具体子类(Concrete Class)
- 实现抽象操作
- 重写钩子方法(按需)
三、实战代码示例:饮料制作系统
1. 抽象模板类 - BeverageTemplate
java
public abstract class BeverageTemplate {
// 模板方法(final防止子类修改流程)
public final void prepareBeverage() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
// 具体方法(通用步骤)
private void boilWater() {
System.out.println("烧开水");
}
private void pourInCup() {
System.out.println("倒入杯中");
}
// 抽象方法(子类必须实现)
protected abstract void brew();
protected abstract void addCondiments();
// 钩子方法(提供默认实现)
protected boolean customerWantsCondiments() {
return true; // 默认加调料
}
}
2. 具体子类 - 咖啡制作
java
public class Coffee extends BeverageTemplate {
@Override
protected void brew() {
System.out.println("用沸水冲泡咖啡粉");
}
@Override
protected void addCondiments() {
System.out.println("加入糖和牛奶");
}
// 重写钩子方法(用户选择是否加糖)
@Override
protected boolean customerWantsCondiments() {
String answer = getUserInput();
return answer.toLowerCase().startsWith("y");
}
private String getUserInput() {
System.out.print("是否加糖和牛奶?(y/n): ");
Scanner scanner = new Scanner(System.in);
return scanner.nextLine();
}
}
3. 具体子类 - 茶制作
java
public class Tea extends BeverageTemplate {
@Override
protected void brew() {
System.out.println("用80℃水浸泡茶叶5分钟");
}
@Override
protected void addCondiments() {
System.out.println("加入柠檬片");
}
}
4. 客户端调用
java
public class Main {
public static void main(String[] args) {
System.out.println("===== 制作咖啡 =====");
BeverageTemplate coffee = new Coffee();
coffee.prepareBeverage();
System.out.println("\n===== 制作茶 =====");
BeverageTemplate tea = new Tea();
tea.prepareBeverage();
}
}
四、模板方法模式的优势
- 代码复用 :封装不变部分(如
boilWater()
),扩展可变部分 - 反向控制:父类调用子类操作(好莱坞原则:"Don't call us, we'll call you")
- 符合开闭原则:增加新子类无需修改父类
- 流程标准化:确保核心算法流程不被破坏
五、典型应用场景
- 框架设计:Spring JdbcTemplate、Hibernate模板
- 批量处理:数据校验、报表生成等固定流程
- 算法框架:如排序算法中比较逻辑的抽象
- 生命周期管理:Servlet的init()/service()/destroy()
六、与策略模式对比
特性 | 模板方法模式 | 策略模式 |
---|---|---|
实现方式 | 继承 | 组合 |
侧重点 | 算法步骤扩展 | 算法整体替换 |
灵活性 | 子类受限于父类结构 | 完全自由的算法替换 |
代码复用 | 父类提供公共代码 | 策略之间独立无复用 |
七、最佳实践建议
- 模板方法声明为final:防止子类重写核心流程
- 尽量减少抽象方法数量:避免子类实现负担过重
- 合理使用钩子方法:在关键扩展点提供控制位
- 命名规范 :模板方法使用
doXXX()
形式命名步骤方法
总结
模板方法模式通过封装不变部分、扩展可变部分,完美实现了代码复用与扩展性的平衡。在Java开发中,无论是框架设计(如Spring的JdbcTemplate)还是业务逻辑处理,都能看到它的身影。掌握此模式,将使你的代码更具架构性和可维护性。
思考题:在Spring框架中,哪些模块使用了模板方法模式?欢迎在评论区分享你的发现!
作者 :Java技术架构
版权声明 :本文为博主原创文章,转载请注明出处
标签:#设计模式 #模板方法模式 #Java开发 #代码复用 #架构设计