当前位置: 首页 > news >正文

模板方法模式:优雅封装算法骨架

目录

一、模板方法模式

1、结构

2、特性

3、优缺点

3.1、优点

3.2、缺点

4、使用场景

5、实现示例

5.1、抽象类

5.2、实现类

5.3、测试类


一、模板方法模式

模板方法模式(Template Method Pattern)是一种行为设计模式,它在一个方法中定义了一个算法的骨架,而将一些步骤的实现延迟到子类中。

通过这种方式,模板方法模式可以将步骤的执行顺序控制在父类中,同时允许子类覆盖特定步骤的实现以满足具体需要。


1、结构

模板方法模式包含以下主要角色:

  1. 抽象类(Abstract Class)

    • 定义抽象的基本操作,子类将重定义它们以实现算法的特定步骤

    • 实现一个模板方法,定义算法的骨架

  2. 具体类(Concrete Class)

    • 实现基本操作以完成算法中与特定子类相关的步骤

2、特性

    固定算法结构:模板方法通过定义算法的骨架,确保算法的固定执行顺序。
    可扩展步骤:子类可以覆盖父类中定义的抽象方法,从而扩展或修改某些步骤,而不影响整体算法的结构。
    不可变模板方法:模板方法通常使用 final 修饰,这样子类就不能重写这个方法,从而保证了算法骨架的稳定性。

3、优缺点


3.1、优点

    代码复用:通过在抽象类中定义公用的算法结构,可以减少代码重复,提高代码复用性。
    灵活性和可扩展性:子类可以根据具体需求覆盖抽象方法,从而实现不同的具体行为,这提高了系统的灵活性和可扩展性。
    控制反转:模板方法模式实现了一种变相的控制反转,由父类调用子类实现的具体方法,减少了子类对父类的依赖。

3.2、缺点

    过度设计:如果算法步骤很简单或变化不大,使用模板方法模式可能导致过度设计,引入不必要的复杂性。
    实现不直观:模板方法模式涉及继承和多态,对某些人来说可能不是特别直观,需要详细文档说明才能正确理解和使用。

4、使用场景

  1. 一次性实现算法的不变部分,将可变部分留给子类实现

  2. 各子类中公共的行为应被提取出来集中到公共父类中

  3. 控制子类扩展,只允许在特定点进行扩展

5、实现示例


5.1、抽象类
 
/*** 抽象类 - 饮料制作模板* 定义了制作饮料的算法骨架*/
public abstract class BeverageTemplate {// 模板方法 - 定义制作饮料的步骤(算法骨架)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();// 钩子方法 - 顾客是否要加调料(默认返回true,子类可覆盖)protected boolean customerWantsCondiments() {return true;}
}
5.2、实现类

具体子类 - 咖啡

/*** 具体子类 - 咖啡*/
public class Coffee extends BeverageTemplate {@Overrideprotected void brew() {System.out.println("冲泡咖啡粉");}@Overrideprotected void addCondiments() {System.out.println("加入糖和牛奶");}// 覆盖钩子方法 - 询问用户是否要加调料@Overrideprotected boolean customerWantsCondiments() {String answer = getUserInput();return answer.toLowerCase().startsWith("y");}}

具体子类 - 茶

/*** 具体子类 - 茶*/
public class Tea extends BeverageTemplate {@Overrideprotected void brew() {System.out.println("浸泡茶叶");}@Overrideprotected void addCondiments() {System.out.println("加入柠檬");}// 覆盖钩子方法 - 茶默认不加调料@Overrideprotected boolean customerWantsCondiments() {return false;}
}

5.3、测试类

public class BeverageTest {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();}
}

结果:

======= 制作咖啡 =======
烧开水
冲泡咖啡粉
将饮料倒入杯子
您的咖啡要加糖和牛奶吗 (y/n)? y
加入糖和牛奶======= 制作茶 =======
烧开水
浸泡茶叶
将饮料倒入杯子
http://www.lryc.cn/news/614988.html

相关文章:

  • MX 播放器:安卓设备上的全能视频播放器
  • 浅谈 VM 桥接模式:让虚拟机像真实电脑一样接入网络
  • SimBA算法实现过程
  • day 36_2025-08-09
  • Gltf 模型 加载到 Cesium 的坐标轴映射浅谈
  • Mysql 分页查询优化
  • 使用lightGCN完整训练用户 + 商品向量的 3 步指南
  • jenkins-飞书通知机制
  • Windows系统NUL文件删除问题解决
  • 如何学习 react native 和 Expo
  • Spark02 - SparkContext介绍
  • Java基础-完成局域网内沟通软件的开发
  • 【和春笋一起学C++】(三十三)名称空间的其他特性
  • C++安全异常设计
  • 可泛化双手操作机器人基准测试:CVPR 2025 MEIS 研讨会 RoboTwin 双臂协作挑战赛
  • 【渲染流水线】[几何阶段]-[图元装配]以UnityURP为例
  • 第15届蓝桥杯Scratch选拔赛初级及中级(STEMA)2024年1月28日真题
  • Leetcode-19. 删除链表的倒数第 N 个结点
  • ORA-600 kcratr_nab_less_than_odr和ORA-600 4194故障处理---惜分飞
  • 莫比乌斯反演学习笔记
  • FFMPEG将H264转HEVC时,码率缩小多少好,以及如何通过SSIM(Structural Similarity Index结构相似性指数)衡量转码损失
  • PDF编辑工具,免费OCR识别表单
  • .htaccess 文件上传漏洞绕过总结
  • springBoot集成easyExcel 实现文件上传
  • linux安装php
  • 模板引擎art-template
  • 深入剖析Spring MVC核心原理:从请求到响应的魔法解密
  • AI 算法优化实战指南:从理论到部署的全流程优化策略
  • K-means聚类学习:原理、实践与API解析
  • 从反射到方法句柄:深入探索Java动态编程的终极解决方案