设计模式——模板方法模式

模板方法模式 (Template Method Pattern)

什么是模板方法模式?

模板方法模式是一种行为型设计模式,它允许你在父类中定义一个算法的框架,而将一些步骤的实现延迟到子类中

简单来说:模板方法模式就是"模板",父类定义框架,子类实现细节。

生活中的例子

想象一下:

  • 做菜:准备食材 → 烹饪 → 装盘(步骤相同,具体做法不同)
  • 考试:答题 → 交卷(步骤相同,具体内容不同)
  • 旅游:订票 → 出行 → 游玩 → 返回(步骤相同,具体安排不同)

为什么需要模板方法模式?

传统方式的问题

java 复制代码
// 每个子类都要重复定义框架
class A {
    public void doSomething() {
        step1();
        step2();
        step3();
    }
}

class B {
    public void doSomething() {
        step1();
        step2();
        step3();
    }
}

问题

  1. 代码重复:框架代码重复
  2. 难以维护:修改框架需要修改多个类
  3. 不一致:框架可能不一致

模板方法模式的优势

java 复制代码
// 父类定义框架,子类实现细节
abstract class Template {
    public void doSomething() {
        step1();
        step2();
        step3();
    }
    
    protected abstract void step1();
    protected abstract void step2();
    protected abstract void step3();
}

优势

  1. 代码复用:框架代码复用
  2. 易于维护:修改框架只需修改父类
  3. 一致性:框架保持一致
  4. 扩展容易:新增子类很容易

模板方法模式的结构

复制代码
┌─────────────────────┐
│  AbstractClass      │  抽象类
├─────────────────────┤
│ + templateMethod()  │
│   : void            │
│ # primitiveOp1():   │
│   void              │
│ # primitiveOp2():   │
│   void              │
│ # primitiveOp3():   │
│   void              │
└──────────┬──────────┘
           │ 继承
           ├──┬──────────────────┬──────────────┐
           │                    │              │
┌──────────┴──────┐  ┌───────────┴───────┐  ┌───┴────────┐
│ ConcreteClass1   │  │ ConcreteClass2    │  │ ...       │  具体类
├─────────────────┤  ├───────────────────┤  ├────────────┤
│ + primitiveOp1() │  │ + primitiveOp1()   │  │            │
│ + primitiveOp2() │  │ + primitiveOp2()   │  │            │
│ + primitiveOp3() │  │ + primitiveOp3()   │  │            │
└─────────────────┘  └───────────────────┘  └────────────┘

代码示例

1. 定义抽象类

java 复制代码
/**
 * 抽象类:做菜
 */
public abstract class CookDish {
    /**
     * 模板方法:定义做菜的流程
     */
    public final void cook() {
        prepareIngredients();
        cookDish();
        serveDish();
    }
    
    /**
     * 基本方法:准备食材
     */
    protected abstract void prepareIngredients();
    
    /**
     * 基本方法:做菜
     */
    protected abstract void cookDish();
    
    /**
     * 基本方法:上菜
     */
    protected abstract void serveDish();
}

2. 定义具体类

java 复制代码
/**
 * 具体类:做宫保鸡丁
 */
public class KungPaoChicken extends CookDish {
    @Override
    protected void prepareIngredients() {
        System.out.println("准备食材:鸡胸肉,花生米,干辣椒,花椒,葱,姜,蒜");
    }
    
    @Override
    protected void cookDish() {
        System.out.println("做菜步骤:");
        System.out.println("1. 鸡肉切丁,腌制");
        System.out.println("2. 花生米炸香盛起");
        System.out.println("3. 热锅下油,炒鸡丁");
        System.out.println("4. 加入干辣椒、花椒爆香");
        System.out.println("5. 调味,加入花生米翻炒");
    }
    
    @Override
    protected void serveDish() {
        System.out.println("上菜:宫保鸡丁做好了!");
    }
}

/**
 * 具体类:做西红柿炒鸡蛋
 */
public class TomatoEggs extends CookDish {
    @Override
    protected void prepareIngredients() {
        System.out.println("准备食材:西红柿2个,鸡蛋3个,葱,盐,糖");
    }
    
    @Override
    protected void cookDish() {
        System.out.println("做菜步骤:");
        System.out.println("1. 西红柿切块,鸡蛋打散");
        System.out.println("2. 热锅下油,炒鸡蛋盛起");
        System.out.println("3. 下西红柿炒出汁");
        System.out.println("4. 加入鸡蛋翻炒,调味");
    }
    
    @Override
    protected void serveDish() {
        System.out.println("上菜:西红柿炒鸡蛋做好了!");
    }
}

3. 使用模板方法

java 复制代码
/**
 * 模板方法模式测试类
 * 演示如何使用模板方法模式做菜
 */
public class TemplateMethodTest {
    
    public static void main(String[] args) {
        System.out.println("=== 模板方法模式测试 ===\n");
        
        // 做西红柿炒鸡蛋
        System.out.println("--- 做西红柿炒鸡蛋 ---");
        CookDish tomatoEggs = new TomatoEggs();
        tomatoEggs.cook();
        
        System.out.println("\n--- 做宫保鸡丁 ---");
        CookDish kungPaoChicken = new KungPaoChicken();
        kungPaoChicken.cook();
        
        System.out.println("\n=== 模板方法模式的优势 ===");
        System.out.println("1. 代码复用:框架代码复用");
        System.out.println("2. 易于维护:修改框架只需修改父类");
        System.out.println("3. 一致性:框架保持一致");
        System.out.println("4. 扩展容易:新增子类很容易");
        System.out.println("5. 控制扩展:父类控制扩展点");
        
        System.out.println("\n=== 实际应用场景 ===");
        System.out.println("1. Servlet:HttpServlet的doGet、doPost");
        System.out.println("2. JDBC:JDBC的执行流程");
        System.out.println("3. Spring:JdbcTemplate、RestTemplate");
        System.out.println("4. 生命周期:对象的生命周期管理");
        System.out.println("5. 算法框架:算法框架的实现");
        
        System.out.println("\n=== 钩子方法 ===");
        System.out.println("钩子方法是在模板方法中提供扩展点的方法:");
        System.out.println("- 可以在子类中覆盖");
        System.out.println("- 可以在模板方法中条件调用");
        System.out.println("- 提供更多的灵活性");
    }
}

模板方法模式的优点

  1. 代码复用:框架代码复用
  2. 易于维护:修改框架只需修改父类
  3. 一致性:框架保持一致
  4. 扩展容易:新增子类很容易
  5. 控制扩展:父类控制扩展点

模板方法模式的缺点

  1. 继承限制:只能通过继承扩展
  2. 类数量增加:每个实现都需要一个子类

适用场景

  1. 步骤固定:算法的步骤固定,但具体实现不同
  2. 代码复用:需要复用框架代码
  3. 控制扩展:需要控制扩展点

常见应用场景

  • Servlet:HttpServlet的doGet、doPost
  • JDBC:JDBC的执行流程
  • Spring:JdbcTemplate、RestTemplate

使用建议

  • 步骤固定:使用模板方法模式
  • 代码复用:使用模板方法模式
  • 步骤不固定:直接使用策略模式

注意事项

⚠️ 模板方法模式虽然有用,但要注意:

  • 不要让模板方法过于复杂
  • 考虑使用钩子方法
相关推荐
Java后端的Ai之路1 天前
【Python 教程15】-Python和Web
python
冬奇Lab1 天前
一天一个开源项目(第15篇):MapToPoster - 用代码将城市地图转换为精美的海报设计
python·开源
二十雨辰1 天前
[python]-AI大模型
开发语言·人工智能·python
Yvonne爱编码1 天前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
前端摸鱼匠1 天前
YOLOv8 环境配置全攻略:Python、PyTorch 与 CUDA 的和谐共生
人工智能·pytorch·python·yolo·目标检测
WangYaolove13141 天前
基于python的在线水果销售系统(源码+文档)
python·mysql·django·毕业设计·源码
AALoveTouch1 天前
大麦网协议分析
javascript·python
ZH15455891311 天前
Flutter for OpenHarmony Python学习助手实战:自动化脚本开发的实现
python·学习·flutter
xcLeigh1 天前
Python入门:Python3 requests模块全面学习教程
开发语言·python·学习·模块·python3·requests
xcLeigh1 天前
Python入门:Python3 statistics模块全面学习教程
开发语言·python·学习·模块·python3·statistics