设计模式之 模板方法模式

news2024/11/26 17:36:27

模板方法模式是行为型设计模式的一种。它定义了一个算法的骨架,并将某些步骤的实现延迟到子类中。模板方法模式允许子类在不改变算法结构的情况下重新定义算法的某些特定步骤。

模板方法模式的核心在于:

  • 封装算法的骨架:通过父类中的模板方法定义算法的执行顺序和框架,保证算法结构的一致性。
  • 委派细节实现:通过抽象方法的方式,允许子类根据自己的需求来提供具体实现,增强了算法的灵活性。

一、模板方法模式的结构

模板方法模式的核心是一个“模板方法”,它通常是一个在父类中定义的具体方法,里面包含了步骤的调用,而步骤的具体实现交给子类。下面是模板方法模式的基本结构:

  1. 抽象类(Abstract Class)

    定义一个模板方法,包含了算法的框架。模板方法通常是具体的方法,它调用一些抽象方法,并通过这些抽象方法将某些步骤的实现委托给子类。
    声明一些抽象方法,这些方法将由子类具体实现,代表算法中的具体步骤。
  2. 具体类(Concrete Class)

    实现抽象类中的抽象方法,提供每个步骤的具体实现。
  3. 模板方法(Template Method)

    在抽象类中定义的具体方法,它为整个算法提供了固定的执行流程和框架。子类可以在模板方法的框架中执行其特定的步骤。

二、模板方法模式的实现

假设我们正在设计一个做菜的程序。做菜的步骤大致是固定的:起锅,热油,加菜,加调料,出锅。不同的菜肴有相同的烹饪步骤,可以通过模板方法来实现不同菜肴的流程。

  • 抽象类
    public abstract class AbstractCook {
    
        public void cookProcess(){
            begin();
            pourOil();
            addVegetable();
            addSauce();
            end();
        }
    
        public void begin(){
            System.out.println("起锅");
        }
    
        public void pourOil(){
            System.out.println("烧油");
        }
    
        public abstract void addVegetable();
    
        public abstract void addSauce();
    
        public void end(){
            System.out.println("出锅");
        }
    }
  • 具体类
    public class CookCabbage extends AbstractCook{
        @Override
        public void addVegetable() {
            System.out.println("加白菜");
        }
    
        @Override
        public void addSauce() {
            System.out.println("加醋,加盐");
        }
    }
    
    public class CookCarrot extends AbstractCook{
        @Override
        public void addVegetable() {
            System.out.println("加胡萝卜");
        }
    
        @Override
        public void addSauce() {
            System.out.println("加盐,加味精");
        }
    }
  • 客户端
    public class Client {
        public static void main(String[] args) {
            AbstractCook cook = new CookCabbage();
            cook.cookProcess();
        }
    }
    
  • 运行结果

三、模板方法模式的优缺点

优点:
  1. 代码复用:模板方法模式将算法的公共部分提取到父类中,避免了重复代码,提高了代码复用性。
  2. 灵活性:尽管算法框架是固定的,但通过子类可以实现特定步骤的变化,符合开闭原则(对扩展开放,对修改封闭)。
  3. 控制反转:模板方法模式通过父类控制了算法的结构,子类只需关注具体的实现细节,不必关心算法框架。
缺点:
  1. 过度设计:如果算法结构简单,或者算法变化较小,使用模板方法模式可能会显得过于复杂,增加了设计的复杂度。
  2. 对子类依赖:子类必须依赖父类提供的模板方法和结构,这可能导致子类与父类之间耦合较高。子类只能按照父类定义的步骤来实现,无法自由调整流程。

四、模板方法模式的应用场景

模板方法模式适用于以下情况:

  1. 算法框架稳定,步骤可变

    当算法框架的结构不变,但具体的实现步骤可以变化时,模板方法模式是非常合适的选择。子类只需要实现算法中的具体步骤即可,而不需要关心框架本身的设计。
  2. 操作顺序固定,步骤可扩展

    比如游戏中的回合制战斗,或者一些具有固定执行顺序的流程,模板方法模式可以帮助固定这些步骤的顺序,并允许不同的子类根据需要改变具体的操作。
  3. 避免代码重复

    如果某个系统中有多个操作流程,且这些流程中有重复的步骤,那么模板方法模式可以有效地提取出这些共通的部分,从而减少重复代码。
  4. 框架的设计

    模板方法模式经常用于设计框架类。一个框架可以提供一个模板方法,子类在继承框架时只需实现其中的一些步骤。
现实生活中的例子:
  • 软件测试框架:在自动化测试框架中,测试步骤往往包括初始化、执行测试、清理环境等,模板方法模式可以帮助确保这些步骤的一致性,而允许子类定义具体的测试方法。
  • 文件处理:比如读取CSV文件、XML文件、JSON文件等,虽然不同的文件格式有不同的解析方法,但读取文件、解析文件和处理数据的步骤通常是相似的,模板方法模式可以用来构建一个统一的文件处理框架。

五、模板方法模式与其他设计模式的关系

模板方法模式与其他行为型设计模式有一些相似性和不同之处:

  1. 模板方法模式 vs 策略模式

    • 模板方法模式:定义了算法的骨架,允许子类实现具体的步骤,但整体算法框架不可改变。
    • 策略模式:允许算法在运行时改变,客户端可以选择不同的策略来完成任务,通常是通过组合来实现不同的策略,而不是通过继承来实现算法的变化。
  2. 模板方法模式 vs 状态模式

    • 状态模式:允许对象根据其内部状态的不同来改变其行为,状态是动态变化的。
    • 模板方法模式:则是在父类中定义一个固定的算法框架,子类仅需要实现某些步骤,而状态变化并不会影响整个算法的框架。

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

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

相关文章

学习threejs,使用设置bumpMap凹凸贴图创建褶皱,实现贴图厚度效果

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.MeshPhongMaterial高…

日常开发记录-正确的prop传参,reduce搭配promise的使用

日常开发记录-正确的prop传参&#xff0c;reduce搭配promise的使用 1.正确的prop传参2.reduce搭配promise的使用 1.正确的prop传参 一般会的父组件传参子组件 //父组件 <A :demodata.sync"testData" :listData.sync"testData2"></A> data ()…

RedHat 10 Beta Install

RedHat 10 beta 前言 Red Hat Enterprise Linux 10.0 Beta 附带内核版本 6.11.0,该版本为以下架构提供最低要求版本支持(括号中注明) AMD 和 Intel 64 位架构(x86-64-v3)64 位 ARM 架构(ARMv8.0-A)IBM Power Systems,小端(POWER9)64 位 IBM Z (z14)RHEL 安装程序的主…

泥石流灾害风险评估与模拟丨AI与R语言、ArcGIS、HECRAS融合,提升泥石流灾害风险预测的精度和准确性

目录 第一章 理论基础 第二章 泥石流风险评估工具 第三章 数据准备与因子提取 第四章 泥石流灾害评价 第五章 HECRAS软件的应用 第六章 操作注意事项与模型优化 泥石流灾害的频发与严重后果&#xff0c;已成为全球范围内防灾减灾工作的重大挑战。随着科技的不断进步&…

android 音效可视化--Visualizer

Visualizer 是使应用程序能够检索当前播放音频的一部分以进行可视化。它不是录音接口&#xff0c;仅返回部分低质量的音频内容。但是&#xff0c;为了保护某些音频数据的隐私&#xff0c;使用 Visualizer 需要 android.permission.RECORD_AUDIO权限。传递给构造函数的音频会话 …

汽车HiL测试:利用TS-GNSS模拟器掌握硬件性能的仿真艺术

一、汽车HiL测试的概念 硬件在环&#xff08;Hardware-in-the-Loop&#xff0c;简称HiL&#xff09;仿真测试&#xff0c;是模型基于设计&#xff08;Model-Based Design&#xff0c;简称MBD&#xff09;验证流程中的一个关键环节。该步骤至关重要&#xff0c;因为它整合了实际…

基于Boost库的搜索引擎

本专栏内容为&#xff1a;项目专栏 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;基于Boots的搜索引擎 &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &#x1f339;&#x1f339;&#x1f339;关注我带你学习编程知识…

二叉树oj题解析

二叉树 二叉树的最近公共祖先什么是最近公共祖先&#xff1f;leetcode中求二叉树中最近公共祖先解题1.解题2. 根据二叉树创建字符串 二叉树的最近公共祖先 什么是最近公共祖先&#xff1f; 最近的公共祖先指的是这一棵树中两个节点中深度最大的且公共的祖先节点就是最近祖先节…

AI赋能电商:构建高效、智能化的新零售生态

随着人工智能&#xff08;AI&#xff09;技术的不断进步&#xff0c;其在电商领域的应用日益广泛&#xff0c;从购物推荐到供应链管理&#xff0c;再到商品定价&#xff0c;AI正在全面改变传统电商的运营模式&#xff0c;并推动行业向智能化和精细化方向发展。本文将探讨如何利…

【从零开始的LeetCode-算法】43. 网络延迟时间

有 n 个网络节点&#xff0c;标记为 1 到 n。 给你一个列表 times&#xff0c;表示信号经过 有向 边的传递时间。 times[i] (ui, vi, wi)&#xff0c;其中 ui 是源节点&#xff0c;vi 是目标节点&#xff0c; wi 是一个信号从源节点传递到目标节点的时间。 现在&#xff0c;…

【数据结构】树——链式存储二叉树的基础

写在前面 书接上文&#xff1a;【数据结构】树——顺序存储二叉树 本篇笔记主要讲解链式存储二叉树的主要思想、如何访问每个结点、结点之间的关联、如何递归查找每个结点&#xff0c;为后续更高级的树形结构打下基础。不了解树的小伙伴可以查看上文 文章目录 写在前面 一、链…

泷羽sec-linux

基础之linux 声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团…

重新定义社媒引流:AI社媒引流王如何为品牌赋能?

在社交媒体高度竞争的时代&#xff0c;引流已经不再是单纯追求流量的数字游戏&#xff0c;而是要找到“对的用户”&#xff0c;并与他们建立真实的连接。AI社媒引流王通过技术创新和智能策略&#xff0c;重新定义了社媒引流的方式&#xff0c;帮助品牌在精准触达和高效互动中脱…

centos 服务器 docker 使用代理

宿主机使用代理 在宿主机的全局配置文件中添加代理信息 vim /etc/profile export http_proxyhttp://127.0.0.1:7897 export https_proxyhttp://127.0.0.1:7897 export no_proxy"localhost,127.0.0.1,::1,172.171.0.0" docker 命令使用代理 例如我想在使用使用 do…

WebRTC音视频同步原理与实现详解(上)

第一章、RTP时间戳与NTP时间戳 1.1 RTP时间戳 时间戳&#xff0c;用来定义媒体负载数据的采样时刻&#xff0c;从单调线性递增的时钟中获取&#xff0c;时钟的精度由 RTP 负载数据的采样频率决定。 音频和视频的采样频率是不一样的&#xff0c;一般音频的采样频率有 8KHz、…

Matlab 深度学习工具箱 案例学习与测试————求二阶微分方程

clc clear% 定义输入变量 x linspace(0,2,10000);% 定义网络的层参数 inputSize 1; layers [featureInputLayer(inputSize,Normalization"none")fullyConnectedLayer(10)sigmoidLayerfullyConnectedLayer(1)sigmoidLayer]; % 创建网络 net dlnetwork(layers);% 训…

互联网直播/点播EasyDSS视频推拉流平台视频点播有哪些技术特点?

在数字化时代&#xff0c;视频点播应用已经成为我们生活中不可或缺的一部分。监控技术与视频点播的结合正悄然改变着我们获取和享受媒体内容的方式。这一变革不仅体现在技术层面的进步&#xff0c;更深刻地影响了我们。 EasyDSS视频直播点播平台是一款高性能流媒体服务软件。E…

神经网络(系统性学习二):单层神经网络(感知机)

此前篇章&#xff1a; 神经网络中常用的激活函数 神经网络&#xff08;系统性学习一&#xff09;&#xff1a;入门篇 单层神经网络&#xff08;又叫感知机&#xff09; 单层网络是最简单的全连接神经网络&#xff0c;它仅有输入层和输出层&#xff0c;没有隐藏层。即&#x…

构建 Java Web 应用程序:从 Servlet 到数据库交互(Eclipse使用JDBC连接Mysql数据库)

第 1 部分&#xff1a;环境设置 安装 Java Development Kit (JDK)&#xff1a;下载并安装 JDK。设置 IDE&#xff1a;安装并配置 IDE&#xff08;如 IntelliJ IDEA 或 Eclipse&#xff09;。安装数据库&#xff1a;下载并安装 MySQL 数据库。配置数据库&#xff1a;创建数据库…

进程间通信5:信号

引入 我们之前学习了信号量&#xff0c;信号量和信号可不是一个东西&#xff0c;不能混淆。 信号是什么以及一些基础概念 信号是一种让进程给其他进程发送异步消息的方式 信号是随时产生的&#xff0c;无法预测信号可以临时保存下来&#xff0c;之后再处理信号是异步发送的…