行为型模式-模板方法模式

news2024/11/27 0:32:16

1.概述

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

例如,去银行办理业务一般要经过以下4个流程:取号、排队、办理具体业务、对银行工作人员进行评分等,其中取号、排队和对银行工作人员进行评分的业务对每个客户是一样的,可以在父类中实现,但是办理具体业务却因人而异,它可能是存款、取款或者转账等,可以延迟到子类中实现。

定义:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。

2.结构

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

  • 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。
    (1)模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。
    (2)基本方法:是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:
    • 抽象方法(Abstract Method) :一个抽象方法由抽象类声明、由其具体子类实现
    • 具体方法(Concrete Method) :一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。
    • 钩子方法(Hook Method) :在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。一般钩子方法是用于判断的逻辑方法,这类方法名一般为isXxx,返回值类型为boolean类型。
  • 具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的组成步骤。

3.案例实现

【例】炒菜

炒菜的步骤是固定的,分为倒油、热油、倒蔬菜、倒调料品、翻炒等步骤。现通过模板方法模式来用代码模拟。类图如下:
在这里插入图片描述
代码如下:

package com.itheima.pattern.template;

/**
 * @program: design-patterns
 * @ClassName AbstractClass
 * @description: 抽象类:定义模板方法和基本方法
 * @author: 
 * @create: 2023-01-24 17:03
 * @Version 1.0
 **/
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("炒菜");
    }
}
package com.itheima.pattern.template;

/**
 * @program: design-patterns
 * @ClassName ConcreteClass_BaoCai
 * @description: 爆炒包菜
 * @author: 
 * @create: 2023-01-24 17:10
 * @Version 1.0
 **/
public class ConcreteClass_BaoCai extends AbstractClass {

    @Override
    public void pourVegetable() {
        System.out.println("下锅的蔬菜是包菜");
    }

    @Override
    public void pourSauce() {
        System.out.println("下锅的调料是辣椒");
    }
}
package com.itheima.pattern.template;

/**
 * @program: design-patterns
 * @ClassName ConcreteClass_BaoCai
 * @description: 爆炒菜心
 * @author: 
 * @create: 2023-01-24 17:10
 * @Version 1.0
 **/
public class ConcreteClass_CaiXin extends AbstractClass {

    @Override
    public void pourVegetable() {
        System.out.println("下锅的蔬菜是菜心");
    }

    @Override
    public void pourSauce() {
        System.out.println("下锅的调料是蒜蓉");
    }
}
package com.itheima.pattern.template;

/**
 * @program: design-patterns
 * @ClassName Client
 * @description: 测试类
 * @author: 
 * @create: 2023-01-24 17:12
 * @Version 1.0
 **/
public class Client {
    public static void main(String[] args) {
        // 创建炒菜的对象
        ConcreteClass_BaoCai baoCai = new ConcreteClass_BaoCai();
        // 调用炒菜的方法
        baoCai.cookProcess();
    }
}
注意:为防止恶意操作,一般模板方法都加上 final 关键词。

3.优缺点

  • 优点
    • 提高代码复用性,将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。
    • 实现了反向控制,通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 ,并符合“开闭原则”。
  • 缺点
    • 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
    • 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。

    4.适用场景

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

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

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

相关文章

机器学习(五):机器学习算法分类

文章目录 机器学习算法分类 一、监督学习 1、回归问题 2、分类问题 二、无监督学习 三、半监督学习 四、强化学习 机器学习算法分类 根据数据集组成不同,可以把机器学习算法分为: 监督学习无监督学习半监督学习强化学习一、监督学习 定义&…

Python初学者看过来啊,老油条来复习

嗨嗨嗨,我又又又又来了 目录 一、Python常用的基本语句 1、format字符串格式化 2、连接字符串 3、if...else条件语句 4、for...in、while循环语句 5、import导入 2.详细介绍 对于初学者来说,想要学好Python语言,必须从最基本的知识开…

为了方便项目打包,我用Node写了个git-tag工具

目录 前言 实现过程 起步 npm全局命令 功能实现 功能验证 代码发布 写在最后 前言 在使用git执行打包操作时,我们常常会根据场景在tag中增加一些标识。 以基准版本为1.0.0为例:软件开发初期可以定义1.0.0-alpha.0,开发阶段是1.0.0-b…

【面试克星】【公式少代码少话多】Vins-Mono预积分相关知识点总结与概述

前言 Vins-Mono预积分相关的公式和代码可以在各个博客中找到。本文将充当一个帮助大家快速理解预积分、中值积分相关概述的角色,带大家理解代码,应对面试。 下面会分成三步,来帮助大家充分理解这个过程。步骤是按照顺序来写的。 中值积分和…

学习MapStruct

概述 MapStruct是一个Java注释处理器,用于生成类型安全的bean映射类。 您要做的就是定义一个映射器接口,该接口声明任何必需的映射方法。在编译期间,MapStruct将生成此接口的实现。此实现使用简单的Java方法调用在源对象和目标对象之间进行映…

<<零入门容器云网络实战>>技术专栏之文章目录

建议: 1、资源 零入门容器云网络实战 链接: https://pan.baidu.com/s/1nPLRkAwjItAHmtEU2T1F4g 提取码: rrpd 2、技术沟通渠道 342498897 3、字体颜色说明 绿色字体&#xff0c; 表示已经发表&#xff0c;可以观看 灰色字体&#xff0c; 表示未发表 4、专栏介绍 1 <<…

【小知识点】如何在 git 中取消 __pycache__ 文件

文章目录如何在 git 中取消 **pycache** 文件CryptographyDeprecationWarning 异常如何在 git 中取消 pycache 文件 如果使用 PyCharm 运行代码&#xff0c;会在 Python 脚本所在目录生成 __pycache__ &#xff0c;每次提交到 git 都会包含该目录&#xff0c;本篇博客我们要将其…

插入排序算法的实现和优化~

插入排序的基本思想&#xff1a; 在一个已排好序的记录子集的基础上&#xff0c;每一步将下一个待排序的记录有序插入到已排好序的记录子集中&#xff0c;直到将所有待排记录全部插入为止 直接插入排序&#xff1a; 直接插入排序是一种最基本的插入排序方法&#xff0c;元素…

离线召回与排序介绍

3.3 离线召回与排序介绍 学习目标 目标 了解召回排序作用知道头条推荐召回排序设计应用 无 3.3.1 召回与排序介绍 召回&#xff1a;从海量文章数据中得到若干候选文章召回集合(数量较多) 排序&#xff1a;从召回集合中读取推荐文章&#xff0c;构建样本特征进行排序过滤筛选…

【SpringCloud21】面试题雪花算法

目录1. 问题2.ID生成规则部分硬性要求3.ID号生成系统的可用性要求4.一般通用方案4.1UUID4. 数据库自增主键5. 基于Redis生成全局id策略6. snowflake6.1 概述6.2 结构6.3 源码6.4 工程落地经验6.4.1 糊涂工具包6.4.2 springboot整合雪花算法1.POM2.核心代码IdGeneratorSnowflake…

ElasticSearch7.6.x 学习笔记

ElasticSearch7.6.x 学习笔记 目录 ElasticSearch概述 ElasticSearch&#xff0c;简称es&#xff0c;es是一个开源的高扩展的分布式全文检索引擎&#xff0c;它可以近乎实时的存储、检索数据。且本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理PB级别的数…

Spring事务、事务隔离级别、事务传播机制

Spring事务和事务传播机制一、为什么需要事务&#xff1f;(回顾)二、Spring中事务的实现2.1 MySQL中的事务使用 (回顾)2.2 Spring编程式事务2.3 Spring 声明式事务2.3.1 Transactional 使用2.3.2 Transactional 作用范围2.3.3 Transactional 参数说明2.3.4 注意事项2.3.4 Trans…

【微服务】Nacos注册中心

Nacos和Eureka一样也可以充当服务的注册中心&#xff0c;让我们一起看看有何区别&#xff1f; 点击跳转&#x1f449;【微服务】Eureka注册中心 一.引入 Nacos是阿里巴巴的产品&#xff0c;现在是SpringCloud中的一个组件。相比于Eureka其功能更加丰富&#xff0c;在国内受欢迎…

2. 获取数字证书,搭建nginx服务器,验证https请求

文章目录 一、 前提知识二、获取数字证书三、搭建nginx服务器3.1 安装nginx操作步骤3.2 导入证书3.3 修改nginx配置文件四、验证一、 前提知识 首先我们知道访问域名时,http请求默认端口为80,https为443。那么我们现在就需要对这两个端口进行监听,这里我们就要用到nginx服务…

数据结构 最短路径课设(源码+实验报告+视频讲解)(用了自取)

XIAN TECHNOLOGICAL UNIVERSITY 课程设计报告 实验课程名称 算法与数据结构 专 业&#xff1a; 班 级&#xff1a; 姓 名&#xff1a; 学 号&#xff1a; 实验学时&#xff1a; 指导…

插入排序实现

场景&#xff1a; 插入排序&#xff0c;一般也被称为直接插入排序。 对于少量元素的排序&#xff0c;它是一个有效的算法 。 插入排序是一种最简单的排序方法&#xff0c;它的基本思想是将一个记录插入到已经排好序的有序表中&#xff0c;从而一个新的、记录数增1的有序表。在…

分享135个ASP源码,总有一款适合您

ASP源码 分享135个ASP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c; 135个ASP源码下载链接&#xff1a;https://pan.baidu.com/s/1rHFniMK56P-_qXNY9kKihg?pwdl95g 提取码&#x…

day11文件夹导航条+文件从数据库和cos删除

获取临时凭证&&上传文件 1创建COS_OBJECT对象 new一个&#xff0c;然后就会向你写的url地址获取临时凭证&#xff08;需要引入一个JS&#xff09; 2.写url地址和url的函数&#xff0c;后台写函数获取到临时凭证&#xff0c;有文档直接调用就可&#xff0c;然后后台返回…

【C++】右值引用和移动语义 | 新的类功能 | 可变参数模板

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《吃透西嘎嘎》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;左值引用…

HTTPS 是这样握手的

HTTP协议默认是明文传输&#xff0c;存在一定的安全隐患&#xff0c;容易被中间人窃听和攻击&#xff0c;在 加密解决HTTP协议带来的安全问题 中提到使用哈希、对称加密、非对称加密等方式对数据加密&#xff0c;能解决数据安全的问题。 以上加密方式需要我们手动的使用加密算…