行为设计模式 -模板方法模式- JAVA

news2024/11/17 6:27:12

模板方法模式

    • 一 .简介
    • 二. 案例
      • 2.1 抽象类(Abstract Class)
      • 2.2 具体子类(Concrete Class)
      • 2.3 测试
    • 三. 结论
      • 3.1 优缺点
      • 3.2 适用场景
      • 3.3 要点

前言
这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。

作者:神的孩子都在歌唱

一 .简介

模板方法是一种行为设计模式。模板方法设计模式用于创建方法存根并将某些实现步骤推迟到子类。

百度百科: 模板方法模式定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式。让子类别在不改变算法架构**的情况下,重新定义算法中的某些步骤。

理解: 在面向对象程序设计过程中,我们常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关

通俗理解,就是设计构建一个对象的时候,类的步骤已经固定了,可是某些类的实现逻辑没固定,就将这些实现给子类去做。

让我们通过一个例子来理解这个模式,假如我们想建造房子,建造房子需要步骤是: 打地基(Foundation),立柱子(Pillars),砌墙(wall),和安装窗户(window)。我们没办法更改这个执行步骤,因为只能完成前一步才能进行下一步。如果我想建造一个木房子(Wooden)和一个玻璃房子(glass)地基的实现都是一样的。因此,针对这种情况我们可以创建一个模板方法,然后通过继承这个模板方法,实现对应的子类去建造不同的房子。接下来通过代码来加深理解

image-20240604142208064

模板方法(Template Method)模式包含以下主要角色:

  • 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。

    • 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。

    • 基本方法:是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:

      • 抽象方法(Abstract Method) :一个抽象方法由抽象类声明、由其具体子类实现。

      • 具体方法(Concrete Method) :一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。

      • 钩子方法(Hook Method) :在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。

        一般钩子方法是用于判断的逻辑方法,这类方法名一般为isXxx,返回值类型为boolean类型。

  • 具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的组成步骤。

二. 案例

2.1 抽象类(Abstract Class)

定义模板方法

/**
 * @author chenyunzhi
 * @date 2024/6/4 13:48
 * @Description 房子模板
 */
public abstract class HouseTemplate {

    /**
     * 定义构建房子步骤  final定义防止子类重写
     */
    public final void buildHouse() {
        // 地基
        foundation();
        // 柱子
        pillars();
        // 墙
        wall();
        // 窗户 默认玻璃
        window();
        System.out.println("房子搭建成功");
    }

    /**
     * 写成私有的防止被子类重写
     */
    private void foundation() {
        System.out.println("地基已经打好");
    }

    public abstract void pillars();

    public abstract void wall();

    public void window() {
        System.out.println("玻璃窗户");
    }
    
}

2.2 具体子类(Concrete Class)

木头房子

/**
 * @author chenyunzhi
 * @date 2024/6/4 13:55
 * @Description
 */
public class WoodenHouse extends HouseTemplate{
    @Override
    public void pillars() {
        System.out.println("木头柱子弄好了");
    }

    @Override
    public void wall() {
        System.out.println("木头墙壁弄好了");
    }
    @Override
    public void window() {
        System.out.println("木头窗户弄好了");
    }
}

玻璃房子

/**
 * @author chenyunzhi
 * @date 2024/6/4 13:59
 * @Description 玻璃房子
 */
public class GlassHouse extends HouseTemplate{
    @Override
    public void pillars() {
        System.out.println("玻璃柱子弄好了");
    }

    @Override
    public void wall() {
        System.out.println("玻璃墙壁弄好了");
    }
}

2.3 测试

搭建木头房子和玻璃房子

/**
 * @author chenyunzhi
 * @date 2024/6/4 13:58
 * @Description
 */
public class TemplateMethodPatternTest {
    public static void main(String[] args) {
        System.out.println("------------搭建木头房子-----------");
        WoodenHouse woodenHouse = new WoodenHouse();
        woodenHouse.buildHouse();

        System.out.println("------------搭建玻璃房子-----------");
        GlassHouse glassHouse = new GlassHouse();
        glassHouse.buildHouse();

    }
}

image-20240604140826402

这样我们就能够基于模板去修改子类去搭建我们的房子了

三. 结论

3.1 优缺点

优点:

  • 提高代码复用性

    将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。

  • 实现了反向控制

    通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 ,并符合“开闭原则”。

缺点:

  • 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
  • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。

3.2 适用场景

  • 算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。
  • 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。

3.3 要点

  1. 模板方法应该由某些步骤组成,这些步骤的顺序是固定的,并且某些方法需要不同的实现。模板方法应该是final。
  2. 如果您希望某些方法不被覆盖,您可以将它们设为 Final或者private

作者:神的孩子都在歌唱

本人博客:https://blog.csdn.net/weixin_46654114

转载说明:务必注明来源,附带本人博客连接。

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

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

相关文章

linux从入门到精通--从基础学起,逐步提升,探索linux奥秘(六)

linux从入门到精通–从基础学起,逐步提升,探索linux奥秘(六) 一、linux高级指令(1) 1、hostname指令 1)作用:操作服务器的主机名(读取、设置) 2&#xff0…

huggingface的transformers与datatsets的安装与使用

目录 1.安装 2.分词 2.1tokenizer.encode() 2.2tokenizer.encode_plus () 2.3tokenizer.batch_encode_plus() 3.添加新词或特殊字符 3.1tokenizer.add_tokens() 3.2 token…

Python自动收发邮件的详细步骤与使用方法?

Python自动收发邮件教程?Python怎么实现收发邮件? Python作为一种强大的编程语言,提供了丰富的库和工具,使得自动收发邮件变得简单而高效。AokSend将详细介绍如何使用Python自动收发邮件,帮助读者掌握这一实用技能。 …

【ASE】第四课_护盾效果(有碰撞效果)

今天我们一起来学习ASE插件,希望各位点个关注,一起跟随我的步伐 今天我们来学习护盾的效果。 思路: 1.添加纹理贴图和法线贴图(这里省略) 2.添加护盾边缘顶点扰动效果,也可以理解成变形效果 3.添加碰撞…

关于frp Web界面-----frp Server Dashboard 和 frp Client Admin UI

Web 界面 官方文档:https://gofrp.org/zh-cn/docs/features/common/ui/ 目前 frpc 和 frps 分别内置了相应的 Web 界面方便用户使用。 客户端 Admin UI 服务端 Dashboard 服务端 Dashboard 服务端 Dashboard 使用户可以通过浏览器查看 frp 的状态以及代理统计信…

59 双向循环神经网络_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录双向RNN推理 总结以下为理论部分双向循环神经网络隐马尔可夫模型中的动态规划双向模型定义模型的计算代价及其应用 (**双向循环神经网络的错误应用**)小结练习 双向RNN 这里理解这个图的时候,不要把正向和逆向认为有上下的关系&a…

计算机毕业设计 基于Python的音乐平台的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…

IDE 使用技巧与插件推荐(含例说明)

在使用集成开发环境(IDE)进行编程时,掌握一些技巧和使用高效的插件可以显著提高开发效率。以下是一些通用的IDE使用技巧和插件推荐,适用于多种流行的IDE,如IntelliJ IDEA、Visual Studio Code、PyCharm等。每个技巧和插…

泳池异常检测系统源码分享

泳池异常检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

Pencils Protocol 成市场新宠,生态通证$DAPP价值几何

Pencils Protocol 是 Scroll 生态综合性收益平台,其仅在 Scroll 生态单链 TVL 就已经突破了 3.5 亿美元,同时在上线短短几个月的时间里就积累了超 50 万活跃社区用户。现阶段 Pencils Protocol 已经完成了 DAPP 通证的 TGE ,分别在 Tokensoft…

[SAP ABAP] 锁对象

在SAP中使用锁对象,用于避免在数据库中插入或更改数据时出现不一致的情况 1.创建锁对象 数据准备 学校表(ZDBT_SCH_437) 使用事务码SE11创建锁对象 点击"锁对象"单选按钮,输入以E开头的锁定对象的名称,然后点击创建按钮 锁对象名…

关于宝塔PHP getenv无法获取环境变量问题解决办法

今天有用ThinkPHP8接入阿里云OSS时,需要用的用到getenv()来读取环境变量,因为新版OSS SDK是用环境变更来设置AK的。 现象 正常执行PHP文件,可以取到环境变量;但是通过nginxphp-fpm调用脚本取到不到环境变量 原因 php-fpm为了防止…

【软考】高速缓存的组成

目录 1. 说明2. 组成 1. 说明 1.高速缓存用来存放当前最活跃的程序和数据。2.高速缓存位于CPU 与主存之间。3.容量般在几千字节到几兆字节之间。4.速度一般比主存快 5~10 倍,由快速半导体存储器构成。5.其内容是主存局部域的副本,对程序员来说是透明的。…

【C++】C++中如何处理多返回值、C++中的模板

十四、C中如何处理多返回值 本部分也是碎碎念,因为这些点都是很小的点,构不成一篇文章,所以本篇就是想到哪个点就写哪个点。 1、C中如何处理多个返回值 写过python的同学都知道,当你写一个函数的返回时,那是你想返回…

STM32 F1移植FATFS文件系统 USMART组件测试相关函数功能

STM32 F1移植FATFS文件系统 使用USMART调试组件测试相关函数功能 文章目录 STM32 F1移植FATFS文件系统 使用USMART调试组件测试相关函数功能前言部分主要相关代码# USMART介绍1. mf_scan_files 扫描磁盘文件2. mf_mount 挂载磁盘3. mf_open 打开文件4. mf_read 读数据内容5. mf…

软件测试学习路线图

软件测试工程师是专门从事软件、系统或产品测试和评估的技术专业人士,确保它们符合既定标准并无任何缺陷。通过精心设计和执行测试计划,软件测试工程师发现 Bug、故障和需要改进的领域,从而提高最终产品的可靠性和性能。 软件测试工程师在软…

干货|CNAS-CL01设备部分解读,透彻掌握软件测试实验室设备关键点

CNAS-CL01《检测和校准实验室能力认可准则》是软件测试实验室建立符合CNAS标准的质量管理体系必须要贯彻的一部准则,分为五大核心部分:通用要求、结构要求、资源要求、过程要求和管理体系要求。前面的文章中我们为大家分享了通用要求部分、结构要求部分以…

WebAssembly进阶,vue3 使用 WebAssembly,及 WebAssembly vs JavaScript 的性能对比

目录 核心使用步骤 .c文件.cpp文件编译 使用 Emscripten 转译文件 页面中引入.wasm文件中的函数 WebAssembly vs JavaScript 的性能对比 性能对比关键点: 具体场景 实际案例分析 如果对WebAssembly不熟悉可以前往:WebAssembly最详教程,进行WebAssembly基础学习 Web…

一篇文章弄懂数据结构中的各种排序_插入排序_冒泡排序_快速排序_堆排序_归并排序_基数排序

文章目录 一篇文章弄懂数据结构中的各种排序1.排序的概念2. 插入排序2.1 直接插入排序2.2 折半插入排序2.3 希尔排序 3.冒泡排序3.1 算法原理3.2 性能分析 4.快速排序4.1 算法原理4.2 性能分析 5. 选择排序5.1 简单选择排序5.2 堆排序5.1 算法流程5.2 算法效率分析5.3 堆排序的…

2024CSCO 芦康沙妥珠单抗创造晚期TNBC二线治疗新高度

前言 “魔法子弹”的概念从上世纪初提出,经过一百多年的不断探索,抗体药物偶联物(ADC)从理想照进现实,达到今天百舸争流的盛况,被认为是极具前景的创新疗法,全球范围内已有十余款产品被批准用于…