news 2026/7/12 18:02:40

设计模式学习(15) 23-13 模版方法模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
设计模式学习(15) 23-13 模版方法模式

文章目录

  • 0.个人感悟
  • 1. 概念
  • 2. 适配场景
    • 2.1 适合的场景
    • 2.2 常见场景举例
  • 3. 实现方法
    • 3.1 实现思路
    • 3.2 UML类图
    • 3.3 代码示例
  • 4. 优缺点
    • 4.1 优点
    • 4.2 缺点
  • 5. 源码分析

0.个人感悟

  • 个人对这个模式印象很深,属于是工作中自己无意识地用到过,后面看书才发现原来已有前辈总结出这个模式,并且更加全面
  • 模版方法模式真的是很典型、很实用,建议大家可以在代码中尝试尝试
  • 模版方法整体是基于继承机制的代码复用,有利于感受抽象、封装、继承、多态的魅力
  • 模版方法模式很好地展现了开闭原则和实现开闭地一个方式: 将变化(具体实现)与不变的部分(算法骨架)分离

1. 概念

英文定义(《设计模式:可复用面向对象软件的基础》)

Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without chaging the algorithm’s structure.

中文翻译

定义一个操作中的算法骨架,将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的情况下重新定义算法的某些特定步骤。

理解

  • 模板方法模式是一种行为型设计模式
  • 父类(抽象类)定义了一个算法的固定框架和流程(模板方法)
  • 具体步骤的实现延迟到子类中完成
  • 子类可以重写某些特定步骤,但不能改变算法的整体结构
  • 通过钩子方法(Hook Method)提供额外的扩展点,允许子类对算法的某些部分进行可选的重写

2. 适配场景

2.1 适合的场景

  • 当多个类有相同的方法流程,但某些步骤的实现不同时,需要提取公共行为到父类,避免代码重复
  • 存在固定的算法骨架,但具体步骤需要灵活变化,需要控制子类的扩展方式,确保算法结构不被破坏

2.2 常见场景举例

  • 制作饮料:冲泡咖啡、茶的流程相似(烧水、冲泡、加调料),但具体步骤不同
  • 数据导入处理:读取数据、验证数据、处理数据、保存数据的流程固定,但不同数据源处理方式不同
  • Spring框架的JdbcTemplate:连接数据库、执行SQL、处理结果集、关闭连接的流程固定
  • 各种初始化流程:游戏初始化、应用启动、设备自检等有固定步骤但细节不同的场景

3. 实现方法

3.1 实现思路

  1. 创建抽象类:定义算法的骨架
  2. 定义模板方法:使用final修饰,防止子类改变算法结构
  3. 定义抽象方法:子类必须实现的具体步骤
  4. 定义具体方法:父类提供的默认实现,子类可选择是否重写
  5. 定义钩子方法:提供默认实现,子类可选择重写以影响算法流程
  6. 创建具体子类:实现抽象方法,可选重写钩子方法

3.2 UML类图

角色说明

  • AbstractClass(抽象类):定义模板方法和算法骨架
  • ConcreteClass(具体子类):实现抽象步骤,可选重写钩子方法

3.3 代码示例

制作饮料,冲泡咖啡、茶的流程相似(烧水、冲泡、加调料),但具体步骤不同
定义模版:

publicabstractclassBeverageTemplate{// 定义算法骨架 final防止子类篡改/** * @description 制作饮料 * @author bigHao * @date 2026/1/20 **/publicfinalvoidprepareBeverage(){boilWater();brew();pourInCup();if(customerWantsCondiments()){addCondiments();}hook();}// 通用流程/** * @description 烧水 * @author bigHao * @date 2026/1/20 **/privatevoidboilWater(){System.out.println("烧水");}// 通用流程/** * @description 倒饮料 * @author bigHao * @date 2026/1/20 **/privatevoidpourInCup(){System.out.println("将饮料倒入杯子");}// 特异流程,子类实现/** * @description 酿造 * @author bigHao * @date 2026/1/20 **/protectedabstractvoidbrew();// 特异流程,子类实现/** * @description 添加作料 * @author bigHao * @date 2026/1/20 **/protectedabstractvoidaddCondiments();// 钩子方法-子类可以重写,用于流程控制/** * @description 钩子方法 * @author bigHao * @date 2026/1/20 **/protectedvoidhook(){// 默认空实现}// 钩子方法,用于流程控制,子类可以重写/** * @return boolean 是否需要 * @description 客户需要作料 * @author bigHao * @date 2026/1/20 **/protectedbooleancustomerWantsCondiments(){returntrue;}}

具体实现:

publicclassCoffeeextendsBeverageTemplate{@Overrideprotectedvoidbrew(){System.out.println("沸水冲泡咖啡");}@OverrideprotectedvoidaddCondiments(){System.out.println("加入糖和牛奶");}@Overrideprotectedvoidhook(){super.hook();System.out.println("hook");}}publicclassTeaextendsBeverageTemplate{@Overrideprotectedvoidbrew(){System.out.println("沸水煮茶叶");}@OverrideprotectedvoidaddCondiments(){System.out.println("加入柠檬");}}

测试:

publicclassClient{staticvoidmain(){System.out.println("=== 制作coffee ===");BeverageTemplatecoffee=newCoffee();coffee.prepareBeverage();System.out.println("=== 制作tea ===");BeverageTemplatetea=newTea();tea.prepareBeverage();}}

输出:

=== 制作coffee === 烧水 用非税冲泡咖啡 将饮料倒入杯子 加入糖和牛奶 hook === 制作tea === 烧水 沸水煮茶叶 将饮料倒入杯子 加入柠檬

4. 优缺点

4.1 优点

  • 提高代码复用性:将公共行为提取到父类,避免代码重复
  • 良好的扩展性:通过增加新的子类可以轻松扩展算法
  • 符合开闭原则:对扩展开放(新增子类),对修改关闭(不修改模板方法)
  • 提高可维护性:算法结构清晰,便于理解和维护
  • 封装不变部分:将不变的行为封装在父类,可变行为由子类实现

4.2 缺点

  • 可能导致类数量增加:每个不同的实现都需要一个子类
  • 父类与子类耦合:子类必须实现父类的抽象方法
  • 限制了子类的灵活性:子类不能改变算法的整体结构
  • 继承的固有缺点:Java单继承限制,子类无法继承其他类
  • 调试困难:模板方法中的流程控制可能使调试变得复杂

5. 源码分析

Spring中的HttpServlet类service()方法分析

// javax.servlet.http.HttpServlet 中的模板方法模式应用publicabstractclassHttpServletextendsGenericServlet{// 模板方法protectedvoidservice(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{Stringmethod=req.getMethod();if(method.equals("GET")){// 调用具体方法doGet(req,resp);}elseif(method.equals("POST")){doPost(req,resp);}elseif(method.equals("PUT")){doPut(req,resp);}// ... 其他HTTP方法}// 钩子方法 - 子类需要实现具体处理逻辑protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{// 默认实现:返回405错误(方法不允许)resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);}protectedvoiddoPost(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);}// ... 其他HTTP方法对应的钩子方法}

分析

  1. 模板方法service()方法定义了HTTP请求处理的整体流程
  2. 具体步骤:根据HTTP方法类型(GET、POST等)分发到不同的处理方法
  3. 钩子方法doGet()doPost()等由子类实现具体的业务逻辑
  4. 默认实现:父类提供错误响应的默认实现
  5. 扩展方式:开发者继承HttpServlet,只需重写需要处理的HTTP方法

使用示例

@WebServlet("/user")publicclassUserServletextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{// 处理GET请求:查询用户信息// ...}@OverrideprotectedvoiddoPost(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{// 处理POST请求:创建用户// ...}}

参考:

  • 韩顺平 Java设计模式
  • 张维鹏 Java设计模式之行为型:模板方法模式
  • java_my_life 《JAVA与模式》之模板方法模式
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/11 13:16:27

数据泄露:网络安全领域的新热点

数据泄露:网络安全领域的新热点 近年来,随着数字经济的快速发展,数据成为企业与个人的核心资产,但数据泄露事件也呈 “爆发式增长”—— 从大型企业(如 Facebook、万豪酒店)的亿级用户数据泄露,…

作者头像 李华
网站建设 2026/6/29 23:27:38

基于SpringBoot的校园悬赏任务平台毕业设计源码

博主介绍:✌ 专注于Java,python,✌关注✌私信我✌具体的问题,我会尽力帮助你。一、研究目的本研究旨在构建一个基于SpringBoot框架的校园悬赏任务平台,以满足现代校园环境中学生、教师以及校园内其他参与者对于信息共享、资源整合和任务执行的…

作者头像 李华
网站建设 2026/6/29 4:32:32

收藏!AI核心概念体系梳理(从基础到架构,夯实大模型学习根基)

本文系统梳理AI领域核心概念脉络,清晰拆解人工智能、机器学习、神经网络、深度学习的层级包含关系,详细解析MLP、CNN、RNN、GNN、Transformer五大基础神经网络架构及落地场景。同时从技术范式、学习方法、应用任务三大维度搭建AI知识框架,补充…

作者头像 李华
网站建设 2026/7/8 5:54:39

WX-0813 AI 降噪回音消除模组

一、产品概述WX-0813 是一款高集成度一体化语音处理模组,专为解决音频设备开发中的噪音干扰、回音叠加、功放适配三大核心痛点设计。模组集成 AI 降噪(ENC)、全双工回音消除(AEC)、双声道 5W 数字功放三大功能&#xf…

作者头像 李华
网站建设 2026/7/11 11:41:03

如何实现降本增效:开源医疗物资耗材系统管控采购-库存全流程

引言 多数中小医院物资耗材管理深陷困境——品类繁杂无统一管控,采购、入库、库存全环节数据割裂,常出现耗材短缺或积压;且对接政府统一采购平台流程繁琐,资金占用率高,间接影响临床诊疗效率。 项目介绍 本文聚焦天…

作者头像 李华
网站建设 2026/7/12 5:06:46

课程论文不用愁!宏智树 AI:一键搞定高分作业的智能写作神器

还在为课程论文熬夜爆肝?对着选题抓耳挠腮半天写不出提纲,文献综述复制粘贴凑字数,格式改了八遍还是被老师打回?作为深耕论文写作科普的教育博主,今天就给学生党安利一款课程论文救星 ——宏智树 AI(官网ww…

作者头像 李华