news 2026/5/17 4:06:37

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
设计模式——模板方法模式

模板方法模式 (Template Method Pattern)

什么是模板方法模式?

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

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

生活中的例子

想象一下:

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

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

传统方式的问题

// 每个子类都要重复定义框架classA{publicvoiddoSomething(){step1();step2();step3();}}classB{publicvoiddoSomething(){step1();step2();step3();}}

问题

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

模板方法模式的优势

// 父类定义框架,子类实现细节abstractclassTemplate{publicvoiddoSomething(){step1();step2();step3();}protectedabstractvoidstep1();protectedabstractvoidstep2();protectedabstractvoidstep3();}

优势

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

模板方法模式的结构

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

代码示例

1. 定义抽象类

/** * 抽象类:做菜 */publicabstractclassCookDish{/** * 模板方法:定义做菜的流程 */publicfinalvoidcook(){prepareIngredients();cookDish();serveDish();}/** * 基本方法:准备食材 */protectedabstractvoidprepareIngredients();/** * 基本方法:做菜 */protectedabstractvoidcookDish();/** * 基本方法:上菜 */protectedabstractvoidserveDish();}

2. 定义具体类

/** * 具体类:做宫保鸡丁 */publicclassKungPaoChickenextendsCookDish{@OverrideprotectedvoidprepareIngredients(){System.out.println("准备食材:鸡胸肉,花生米,干辣椒,花椒,葱,姜,蒜");}@OverrideprotectedvoidcookDish(){System.out.println("做菜步骤:");System.out.println("1. 鸡肉切丁,腌制");System.out.println("2. 花生米炸香盛起");System.out.println("3. 热锅下油,炒鸡丁");System.out.println("4. 加入干辣椒、花椒爆香");System.out.println("5. 调味,加入花生米翻炒");}@OverrideprotectedvoidserveDish(){System.out.println("上菜:宫保鸡丁做好了!");}}/** * 具体类:做西红柿炒鸡蛋 */publicclassTomatoEggsextendsCookDish{@OverrideprotectedvoidprepareIngredients(){System.out.println("准备食材:西红柿2个,鸡蛋3个,葱,盐,糖");}@OverrideprotectedvoidcookDish(){System.out.println("做菜步骤:");System.out.println("1. 西红柿切块,鸡蛋打散");System.out.println("2. 热锅下油,炒鸡蛋盛起");System.out.println("3. 下西红柿炒出汁");System.out.println("4. 加入鸡蛋翻炒,调味");}@OverrideprotectedvoidserveDish(){System.out.println("上菜:西红柿炒鸡蛋做好了!");}}

3. 使用模板方法

/** * 模板方法模式测试类 * 演示如何使用模板方法模式做菜 */publicclassTemplateMethodTest{publicstaticvoidmain(String[]args){System.out.println("=== 模板方法模式测试 ===\n");// 做西红柿炒鸡蛋System.out.println("--- 做西红柿炒鸡蛋 ---");CookDishtomatoEggs=newTomatoEggs();tomatoEggs.cook();System.out.println("\n--- 做宫保鸡丁 ---");CookDishkungPaoChicken=newKungPaoChicken();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

使用建议

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

注意事项

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

  • 不要让模板方法过于复杂
  • 考虑使用钩子方法
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 4:56:16

看似平平无奇的00后,居然一跃上岸字节,表示真的卷不过......

又到了一年一度的求职旺季金!三!银!四!在找工作的时候都必须要经历面试这个环节。在这里我想分享一下自己上岸字节的面试经验,过程还挺曲折的,但是还好成功上岸了。大家可以参考一下! 0821测评 …

作者头像 李华
网站建设 2026/5/16 9:17:47

CAS入门

一、先搞懂:为什么需要CAS? 在讲CAS之前,我们先解决一个基础问题:并发场景下,简单的自增操作(比如i)为什么会出问题? 举个例子:你有一个变量int count 0,让1…

作者头像 李华
网站建设 2026/5/16 5:02:16

Dify:一站式AI应用开发平台全解析与Windows部署指南

从零到一,掌握这款让AI应用开发效率提升10倍的开源神器 🎯 什么是Dify? Dify(发音为 /ˈdɪfaɪ/)是一个开源的生成式AI应用开发平台,旨在帮助开发者和企业快速构建并部署生产级的AI应用。它的核心是融合了…

作者头像 李华
网站建设 2026/5/16 11:39:53

怎样用Postman做接口自动化测试及完美的可视化报告

postman官网下载地址: https://www.postman.com/downloads/ 下载后直接双击文件安装: Postman-win64-9.20.3-Setup.exe 根据自己需要修改软件安装路径,后面直接默认安装就可以 1、Jenkins简介 Jenkins是一个开源的软件项目,…

作者头像 李华
网站建设 2026/5/13 13:16:00

校招失败后,在小公司熬了 2 年终于进了百度,竭尽全力....

其实两年前校招的时候就往百度投了一次简历,结果很明显凉了,随后这个理想就被暂时放下了,但是这个种子一直埋在心里这两年除了工作以外,也会坚持写博客,也因此结识了很多优秀的小伙伴,从他们身上学到了特别…

作者头像 李华
网站建设 2026/5/3 1:27:57

卷麻了,00后测试用例写的比我还好,简直无地自容......

经常看到无论是刚入职场的新人,还是工作了一段时间的老人,都会对编写测试用例感到困扰?例如: 如何编写测试用例? 作为一个测试新人,刚开始接触测试,对于怎么写测试用例很是头疼,无法…

作者头像 李华