「全网最细 + 实战源码案例」设计模式——模板方法模式

news/2025/2/4 17:39:05/文章来源:https://www.cnblogs.com/cikiss/p/18698343

核心思想

  • 模板方法模式(Template Method Pattern)是一种行为型设计模式,定义了一个算法的骨架(模板),将某些步骤延迟到子类中实现(在不修改结构的情况下),以避免代码重复,提高代码复用性,保持算法的结构稳定。
  • 核心:
    • 模板方法:在父类中定义一个算法的骨架(即模板方法),其中包含一些抽象方法或钩子方法(hook methods),这些方法由子类实现。
    • 不变部分:算法的整体结构是固定的,由父类控制。
    • 可变部分:算法的某些步骤可以被子类重写,以实现不同的行为。

编辑


结构

1. 抽象类(Abstract Class)

  • 定义算法的骨架(模板方法)。
  • 由一个模板方法和若干个基本方法构成。
    • 模板方法:定义算法骨架,按某种顺序调用其包含的基本方法。
    • 基本方法:实现算法各步骤的方法,是模板方法的组成部分,分为三类:
      • 抽象方法:由抽象类声明,具体子类实现。
      • 具体方法:一个具体方法由一个抽象类或具体类声明并实现,其子类可以覆盖或继承。
      • 钩子方法:抽象类中已实现,包括用于判断的逻辑方法和需要子类重写的空方法。

2. 具体子类(Concrete Class)

  • 实现抽象类中所定义的抽象方法或钩子方法,是一个顶级逻辑的组成步骤。

编辑


现实世界类比

  • 模板方法可用于建造大量房屋。 标准房屋建造方案中可提供几个扩展点, 允许潜在房屋业主调整成品房屋的部分细节。

编辑

  • 每个建造步骤 (例如打地基、 建造框架、 建造墙壁和安装水电管线等) 都能进行微调, 这使得成品房屋会略有不同。

适用场景

  1. 算法复用:当多个类有相似的算法结构,只有某些步骤不同时。
  2. 框架设计: 框架通常定义算法的股价,而将具体实现留给用户。如何 Spring 中的 JdbcTemplate定义了数据库操作的流程,用户只需实现具体的 SQL 语句。
  3. 工作流设计:定义固定的工作流程,但允许某些步骤自定义。

优缺点

优点:

  1. 代码复用:不变的部分放在子类,避免代码重复。
  2. 提高扩展性:子类通过实现抽象方法或重写钩子方法类扩展算法的某些步骤。
  3. 符合开闭原则: 算法整体结构(修改)是封闭的,但具体步骤(扩展)是开放的。

缺点:

  1. 一定程度违反里氏替换原则:子类重写默认步骤后可能无法替代父类。
  2. 缺乏灵活性(相比策略模式) :子类必须继承模板。

实现步骤

  1. 分析目标算法, 确定能否将其分解为多个步骤。 从所有子类的角度出发, 考虑哪些步骤能够通用, 哪些步骤各不相同。
  2. 创建抽象基类并声明一个模板方法和代表算法步骤的一系列抽象方法。 在模板方法中根据算法结构依次调用相应步骤。 可用 final最终修饰模板方法以防止子类对其进行重写。
  3. 虽然可将所有步骤全都设为抽象类型, 但默认实现可能会给部分步骤带来好处, 因为子类无需实现那些方法。
  4. 可考虑在算法的关键步骤之间添加钩子。
  5. 为每个算法变体新建一个具体子类, 它必须实现所有的抽象步骤, 也可以重写部分可选步骤。

示例

编辑

// 抽象类(定义模板方法和基本方法)
public abstract class AbstractClass {// 模板方法定义public final void cookProcess(){pourOil();heatOil();pourVegetable();pourSauce();fry();}public void pourOil(){System.out.println("倒油");}public void heatOil(){System.out.println("热油");}public abstract void pourVegetable();public abstract void pourSauce();public void fry(){System.out.println("翻炒");}
}// 具体子类——包菜
public class BaoCai extends AbstractClass{@Overridepublic void pourVegetable() {System.out.println("下锅的蔬菜是包菜");}@Overridepublic void pourSauce() {System.out.println("下锅的酱料是辣椒");}
}// 具体子类——菜心
public class CaiXin extends AbstractClass{@Overridepublic void pourVegetable() {System.out.println("下锅的蔬菜是菜心");}@Overridepublic void pourSauce() {System.out.println("下锅的酱料是蒜蓉");}
}// 客户端
public class Client {public static void main(String[] args) {AbstractClass baoCai = new BaoCai();baoCai.cookProcess();System.out.println("---------------------------------------------");AbstractClass caiXin = new CaiXin();caiXin.cookProcess();}
}


在源码中的应用

编辑

编辑


与其他模式的关系

  • 工厂方法模式是模板方法模式的一种特殊形式。 同时, 可以作为一个大型 中的一个步骤。
  • 模板方法基于继承机制: 它允许你通过扩展子类中的部分内容来改变部分算法。 策略模式基于组合机制: 你可以通过对相应行为提供不同的策略来改变对象的部分行为。 模板方法在类层次上运作, 因此它是静态的。 策略在对象层次上运作, 因此允许在运行时切换行为。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/878638.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

探索Java动态代理的奥秘:JDK vs CGLIB

动态代理是一种在 运行时动态生成代理类的技术,无需手动编写代理类代码。它通过拦截目标方法的调用,实现对核心逻辑的 无侵入式增强(如日志、事务、权限控制等)。一、关于动态代理 1.1 简介 动态代理是一种在 运行时动态生成代理类 的技术,无需手动编写代理类代码。它通过…

Esp32s3(立创实战派)移植LVGL

Esp32s3(立创实战派)移植LVGL 移植: 使用软件EEZ studio 创建工程选择带EEZ Flow的,可以使用该软件更便捷的功能根据屏幕像素调整画布为320*240复制ui文件至工程 将生成的ui文件夹复制到main文件夹同级目录(ui文件夹在工程文件src中) 工程结构:修改声明头文件路径 首先将u…

字节系AI代码编辑器Trae:免费双模大模型+「Builder模式」

字节跳动技术团队近日正式推出AI代码编辑器Trae(官网:https://www.trae.ai/),这款定位为「自适应AI IDE」的开发工具,凭借其创新功能组合在技术圈引发关注。作为面向下一代开发者的智能编程平台,Trae正在重新定义人机协作的编码体验。 一、核心亮点解析双模大模型免费开放…

RocketMQ实战—3.基于RocketMQ升级订单系统架构

大纲 1.基于MQ实现订单系统核心流程的异步化改造 2.基于MQ实现订单系统和第三方系统的解耦 3.基于MQ实现将订单数据同步给大数据团队 4.秒杀系统的技术难点以及秒杀商详页的架构设计 5.基于MQ实现秒杀系统的异步化架构 6.全面引入MQ的订单系统架构的思维导图1.基于MQ实现订单系…

昆明理工大学2025通信复试真题及答案-通信核心课程综合

0854通信工程信号与系统 吴大正信号与线性系统分析昆工昆明理工大学通信工程817信号与系统考研信号与信息处理通信与信息系统通信工程F002通信核心课程综合通信工程(含宽带网络、移动通信等)

pytorch | softmax(x,dim=-1)参数dim的理解

转自:https://zhuanlan.zhihu.com/p/525276061 首先说一下Softmax函数,公式如下:1. 三维tensor(C,H,W) 一般会设置成dim=0,1,2,-1的情况(可理解为维度索引)。其中2与-1等价,相同效果。 用一张图片来更好理解这个参数dim数值变化:当dim=0时, 是对每一维度相同位置的数值进行…

私人订制新功能——日常

最近开发了一个新功能,以前我都是用纸质笔记做记录的日常生活,后来发现有点麻烦,比如写英语日记的时候,哪天的日记忘记写了还得往前翻太麻烦了,现在打算制作一个功能把这个事情记录下来;功能:是否已经写英语日记记录、举哑铃记录、锻炼握力器记录;

2025 PVC

短线有波上涨

静态代理模式:代码世界的“替身演员”

静态代理是代理模式的一种**实现方式**,其特点是**代理类在编译时就已经确定**,代理类的代码是在程序编译阶段生成的,而不是运行时动态生成。一、关于静态代理 1.1 简介 静态代理是代理模式的一种实现方式,其特点是代理类在编译时就已经确定,代理类的代码是在程序编译阶段…

一个 .NET 开源、免费、功能强大的Windows应用卸载神器

前言 今天大姚给大家分享一个基于 .NET 开源(Apache License)、免费、功能强大的Windows应用卸载神器:Bulk Crap Uninstaller。 项目介绍 Bulk Crap Uninstaller 是一款基于 .NET 开源(Apache License)、免费、功能强大的Windows应用卸载工具,旨在帮助用户快速且有效地移…

强化学习驱动的自适应模型选择与融合用于监督学习

图片来源:Unsplash 上的 Agence Olloweb引言 机器学习模型的选择一直是一个挑战。无论是预测股票价格、诊断疾病,还是优化营销活动,问题始终是:哪个模型最适合我的数据? 传统上,我们依赖交叉验证来测试多个模型——XGBoost、LGBM、随机森林等——然后根据验证性能选择最佳…

Python 与 PostgreSQL 集成:深入 psycopg2 的应用与实践

title: Python 与 PostgreSQL 集成:深入 psycopg2 的应用与实践 date: 2025/2/4 updated: 2025/2/4 author: cmdragon excerpt: PostgreSQL 作为开源关系型数据库的佼佼者,因其强大的功能与性能被广泛应用于各种项目中。而 Python 则因其简洁易用的语法、丰富的库和强大的数…