深入理解设计模式之模板方法模式 1d87ab8b42e98069b6c2c5a3d2710f9a

news2025/4/18 21:22:33

深入理解设计模式之模板方法模式

深入理解设计模式之模板方法模式

在软件开发的漫长征程中,我们常常会遇到各种复杂的业务逻辑,其中部分逻辑具有相似的流程框架,但在具体细节上又有所不同。这种情况下,模板方法模式就如同一位得力助手,能够帮助我们高效地组织和复用代码。本文将通过一个生动的示例,深入剖析模板方法模式的精妙之处。

一、模板方法模式的概念

模板方法模式是一种行为设计模式,它在一个抽象类中定义了一个算法的骨架,将一些步骤的具体实现延迟到子类中。这意味着,子类可以在不改变算法整体结构的前提下,自由地定制某些特定步骤的行为。这种模式极大地提高了代码的复用性,同时也增强了系统的可扩展性和维护性。

二、示例场景:冲泡饮品

为了更好地理解模板方法模式,让我们以冲泡饮品为例。想象一下,我们有两种饮品需要冲泡:茶和咖啡。它们的冲泡过程大致相同,都需要烧水、冲泡、倒入杯子这几个步骤,但在冲泡和添加调料的具体方式上却有所区别。

(一)定义抽象类

首先,我们创建一个名为CaffeineBeverage的抽象类,它将作为我们冲泡饮品的模板。

// 抽象类,定义准备饮料的算法骨架

abstract class CaffeineBeverage {

   // 模板方法,定义了算法的骨架

   final void prepareRecipe() {

       boilWater();

       brew();

       pourInCup();

       if (customerWantsCondiments()) {

           addCondiments();

       }

   }

   // 具体步骤:烧水

   void boilWater() {

       System.out.println("Boiling water");

   }

   // 抽象步骤:冲泡

   abstract void brew();

   // 具体步骤:倒入杯子

   void pourInCup() {

       System.out.println("Pouring into cup");

   }

   // 抽象步骤:添加调料

   abstract void addCondiments();

   // 钩子方法,子类可以重写此方法来控制是否添加调料

   boolean customerWantsCondiments() {

       return true;

   }

}

在这个抽象类中,prepareRecipe方法就是我们的模板方法,它定义了冲泡饮品的整体流程。boilWaterpourInCup方法是所有饮品冲泡过程中都相同的具体步骤,因此在抽象类中直接实现。而brewaddCondiments方法则因饮品而异,所以被定义为抽象方法,需要由具体的子类来实现。此外,customerWantsCondiments是一个钩子方法,子类可以根据需要重写它,以决定是否添加调料。

(二)创建具体子类

接下来,我们创建TeaCoffee两个具体子类,继承自CaffeineBeverage抽象类,并实现其中的抽象方法。

// 茶类,继承 CaffeineBeverage 并实现抽象方法
class Tea extends CaffeineBeverage {
   @Override
   void brew() {
       System.out.println("Steeping the tea");
   }
   @Override
   void addCondiments() {
       System.out.println("Adding lemon");
   }
   // 重写钩子方法,不添加调料
   @Override
   boolean customerWantsCondiments() {
       return false;
   }
}
// 咖啡类,继承 CaffeineBeverage 并实现抽象方法

class Coffee extends CaffeineBeverage {
   @Override
   void brew() {
       System.out.println("Dripping coffee through filter");
   }
   @Override
   void addCondiments() {
       System.out.println("Adding sugar and milk");
   }
}

Tea类中,brew方法实现了泡茶的具体方式 —— 浸泡茶叶,addCondiments方法添加了柠檬作为调料,并且通过重写customerWantsCondiments钩子方法,决定不添加调料。而在Coffee类中,brew方法采用滴滤咖啡的方式,addCondiments方法添加了糖和牛奶作为调料。

(三)测试代码

最后,我们编写一段测试代码来验证模板方法模式的效果。

// 主类,测试模板方法模式

public class Main {
   public static void main(String[] args) {
       System.out.println("Making tea...");
       CaffeineBeverage tea = new Tea();
       tea.prepareRecipe();
       System.out.println("\nMaking coffee...");
       CaffeineBeverage coffee = new Coffee();
       coffee.prepareRecipe();
   }
}

运行上述代码,我们可以看到控制台输出了泡茶和泡咖啡的过程,并且按照各自的实现方式进行了冲泡和添加调料。

三、模板方法模式的优势

代码复用性高:通过将通用的算法骨架封装在抽象类中,避免了在多个子类中重复编写相同的代码,大大提高了代码的复用性。

可维护性强:当需要修改算法的整体结构时,只需在抽象类中进行修改,所有子类会自动继承这些变化,减少了维护的工作量。

可扩展性好:如果需要添加新的饮品冲泡方式,只需创建一个新的子类,继承抽象类并实现相应的抽象方法即可,符合开闭原则。

四、总结

模板方法模式为我们提供了一种优雅的方式来处理具有相似流程但不同细节的业务逻辑。通过将通用部分抽象出来,将变化部分留给子类实现,我们能够有效地提高代码的质量和可维护性。在实际的软件开发中,无论是复杂的业务系统还是简单的工具类库,模板方法模式都有着广泛的应用场景。希望通过本文的介绍,读者能够对模板方法模式有更深入的理解,并在今后的开发中灵活运用这一强大的设计模式。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity入门笔记(缘更)

内容来源SiKi学院的Luna’s Fantasy 文章目录 一、基础知识1.准备2.基础知识1.层级(Layer)2.轴心点3.预制体(Prefab)4.刚体组件(Rigidbody)5.碰撞器组件(BoxCollider) 二、代码1.移动 一、基础知识 1.准备 Unity安装: https://unity.cn 2.基础知识 1.层级(Layer…

【Python】用Python写一个俄罗斯方块玩玩

【Python】用Python写一个俄罗斯方块玩玩 一、引言1.成品效果展示 二、思考准备1.思考设计2.代码设计2.1 游戏页面2.2 控件设计2.2.1 方块生成2.2.2 方块碰撞2.2.3 方块消融2.2.4 游戏主循环2.2.5 游戏窗口 三、游戏完整版 一、引言 今日看到侄子在玩游戏,凑近一看…

记录一次生产中mysql主备延迟问题处理

登录库: mysql -uXXXX -pXXXX -P3306 -hXXXXXX -A 备库上执行:show slave status\G 查看 seconds_Behind_Master,延迟 2705s,而且还一直在增加。 SHOW CREATE TABLE proc_i_income_temp; -- 查看表的结构 show index from proc…

ffmpeg无损转格式的命令行

将ffmpeg.exe拖入命令行窗口 c:\users\zhangsan>D:\ffmpeg-2025-03-11\bin\ffmpeg.exe -i happy.mp4 -c:v copy -c:a copy 格式转换后.mkv -c:v copy 仅做拷贝视频,不重新编码 -c:a copy 仅做拷贝音频 ,不重新编码

强化学习算法系列(五):最主流的算法框架——Actor-Critic算法框架

强化学习算法 (一)动态规划方法——策略迭代算法(PI)和值迭代算法(VI) (二)Model-Free类方法——蒙特卡洛算法(MC)和时序差分算法(TD) (三)基于动作值的算法——Sarsa算法与Q-Learning算法 (四…

设计模式(结构型)-桥接模式

目录 摘要 定义 类图 角色 具体实现 优缺点 优点 缺点 使用场景 使用案例 JDBC 和桥接模式 总结 摘要 在软件开发领域,随着系统规模和复杂性的不断攀升,如何设计出具有良好扩展性、灵活性以及可维护性的软件架构成为关键挑战。桥接模式作为一…

【MySQL】MySQL数据库 —— 简单认识

目录 1. 数据库的介绍 1.1 什么是数据库 1.2 数据库和数据结构之间关系 2. 数据库分类 2.1 关系型数据库(RDBMS) 2.2 非关系型数据库 2.3 区别 一些行内名词简单解释: 3. 关于mysql 主要学什么 4. MySQL中重要的概念 4.1 概念 4…

RNN - 语言模型

语言模型 给定文本序列 x 1 , … , x T x_1, \ldots, x_T x1​,…,xT​,语言模型的目标是估计联合概率 p ( x 1 , … , x T ) p(x_1, \ldots, x_T) p(x1​,…,xT​)它的应用包括 做预训练模型(eg BERT,GPT-3)生成本文&#xff…

过拟合、归一化、正则化、鞍点

过拟合 过拟合的本质原因往往是因为模型具备方差很大的权重参数。 定义一个有4个特征的输入,特征向量为,定义一个模型,其只有4个参数,表示为。当模型过拟合时,这四个权重参数的方差会很大,可以假设为。当经过这个模型后…

【python画图】:从入门到精通绘制完美柱状图

目录 Python数据可视化:从入门到精通绘制完美柱状图一、基础篇:快速绘制柱状图1.1 使用Matplotlib基础绘制1.2 使用Pandas快速绘图 二、进阶篇:专业级柱状图定制2.1 多系列柱状图2.2 堆叠柱状图2.3 水平柱状图 三、专业参数速查表Matplotlib …

基础知识:离线安装docker、docker compose

(1)离线安装docker 确认版本:Ubuntu 18.04 LTS - bionic 确认架构:X86_64 lsb_release -a uname -a 官方指南:https://docs.docker.com/engine/install/ 选择Ubuntu,发现页面上最低是Ubuntu20.04, 不要紧

畅游Diffusion数字人(27):解读字节跳动提出主题定制视频生成技术Phantom

畅游Diffusion数字人(0):专栏文章导航 前言:主题定制视频生成,特别是zero-shot主题定制视频生成,一直是当前领域的一个难点,之前的方法效果很差。字节跳动提出了一个技术主题定制视频生成技术Phantom,效果相比于之前的技术进步非常显著。这篇博客详细解读一下这一工作。 …

《Adaptive Layer-skipping in Pre-trained LLMs》- 论文笔记

作者:Xuan Luo, Weizhi Wang, Xifeng Yan Department of Computer Science, UC Santa Barbara xuan_luoucsb.edu, weizhiwangucsb.edu, xyancs.ucsb.edu 1. 引言与动机 1.1 背景 LLM 的成功与挑战: 大型语言模型 (LLMs) 在翻译、代码生成、推理等任务上取得巨大成…

微信小程序实现table样式,自带合并行合并列

微信小程序在代码编写过程好像不支持原生table的使用&#xff0c;在开发过程中偶尔又得需要拿table来展示。 1.table效果展示 1.wxml <view class"table-container"><view class"table"><view class"table-row"><view cla…

电脑的品牌和配置

我的笔记本是2020年买的&#xff0c;之前的订单找不到了&#xff0c;就知道是联想&#xff0c;不清楚具体的配置。 本文来源&#xff1a;腾讯元宝 检查系统信息&#xff08;Windows&#xff09; 这通常是 ​​联想&#xff08;Lenovo&#xff09;​​ 的型号代码。 81XV 是联想…

Redis面试——常用命令

一、String &#xff08;1&#xff09;设置值相关命令 1.1.1 SET 功能&#xff1a;设置一个键值对&#xff0c;如果键已存在则覆盖旧值语法&#xff1a; SET key value [EX seconds] [PX milliseconds] [NX|XX]EX seconds&#xff1a;设置键的过期时间为 seconds 秒 PX milli…

Swin-Transformer-UNet改进:融合Global-Local Spatial Attention (GLSA) 模块详解

目录 1.模块概述 2.swinUNet网络 3. 完整代码 1.模块概述 Global-Local Spatial Attention (GLSA) 是一种先进的注意力机制模块,专为计算机视觉任务设计,能够同时捕捉全局上下文信息和局部细节特征。 该模块通过创新的双分支结构和自适应融合机制,显著提升了特征表示能…

ubuntu 向右拖动窗口后消失了、找不到了

这是目前单显示器的设置&#xff0c;因为实际只有1个显示器&#xff0c;之前的设置如下图所示&#xff0c;有2个显示器&#xff0c;一个主显示器&#xff0c;一个23寸的显示器 ubuntu 22.04 系统 今天在操作窗口时&#xff0c;向右一滑&#xff0c;发现这个窗口再也不显示了、找…

2025最新版微软GraphRAG 2.0.0本地部署教程:基于Ollama快速构建知识图谱

一、前言 微软近期发布了知识图谱工具 GraphRAG 2.0.0&#xff0c;支持基于本地大模型&#xff08;Ollama&#xff09;快速构建知识图谱&#xff0c;显著提升了RAG&#xff08;检索增强生成&#xff09;的效果。本文手把手教你如何从零部署&#xff0c;并附踩坑记录和性能实测…

libevent服务器附带qt界面开发(附带源码)

本章是入门章节&#xff0c;讲解如何实现一个附带界面的服务器&#xff0c;后续会完善与优化 使用qt编译libevent源码演示视频qt的一些知识 1.主要功能有登录界面 2.基于libevent实现的服务器的业务功能 使用qt编译libevent 下载这个&#xff0c;其他版本也可以 主要是github上…