模板方法详解

news2024/11/15 11:02:57

1.基本介绍

  1. 模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern), 在一个抽象类公开定义了执行 它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
  2. 简单说,模板方法模式 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一 个算法的结构,就可以重定义该算法的某些特定步骤
  3. 这种类型的设计模式属于行为型模式

2.原理类图

在这里插入图片描述

3.具体需求

1.豆浆制作

编写制作豆浆的程序,说明如下:

  • 制作豆浆的流程:选材—>添加配料—>浸泡—>放到豆浆机打碎
  • 通过添加不同的配料,可以制作出不同口味的豆浆
  • 选材、浸泡和放到豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的

2. 模板方法模式方案

在这里插入图片描述

3.具体实现


// 抽象类,表示豆浆	SoyaMilk.java
public abstract class SoyaMilk {
	// 模板方法:可以做成final,不让子类去覆盖
	final void make() {
		select();
		addCondiment();
		soak();
		beat();
	}
	
	//选材料
	void select() { System.out.println("第一步:选择新鲜的豆子"); }
	//添加不同的配料:抽象方法,由子类具体实现
	abstract void addCondiment();
	//浸泡
	void soak() { System.out.println("第三步:豆子和配料开始浸泡3H"); }
	//榨汁
	void beat() { System.out.println("第四步:豆子和配料放入豆浆机榨汁"); }
}

// RedBeanSoyaMilk.java
public class ReadBeanSoyaMilk extends SoyaMilk {
	@Override
	void addCondiment() {
		System.out.println("第二步:加入上好的红豆");
	}
}

// PeanutSoyMilk.java
public class PeanutSoyaMilk extends SoyaMilk {
	@Override
	void addCondiment() {
		System.out.println("第二步:加入上好的花生");
	}
}

// Client.java
public class Client {
	public static void main(String[] args) {
		System.out.println("=======制作红豆豆浆=======");
		SoyaMilk redBeanSoyaMilk = new ReadBeanSoyaMilk();
		redBeanSoyaMilk.make();
		
		System.out.println("=======制作花生豆浆=======");
		SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
		peanutSoyaMilk.make();
	}
}

4.模板方法模式的钩子方法

在模板方法模式的父类中,可以定义一个方法,它默认不做任何事,子类可以视情况要不要覆盖它,该方法称为“钩子”。还是用上面做豆浆的例子来讲解,比如,我们还希望制作纯豆浆,不添加任何的配料,请使用钩子方法对前面的模板方法进行改造。代码实现如下:

// RedBeanSoyaMilk.java/PeanutSoyaMilk.java同上,略

//抽象类,表示豆浆,SoyaMilk
public abstract class SoyaMilk {

	//模板方法:可以做成final,不让子类去覆盖
	final void make() {
		select();
		if(customerWantCondiment()) {
			addCondiment();
		}	
		soak();
		beat();
	}

	//1.选材料
	void select() { System.out.println("第一步:选择新鲜的豆子"); }
	//2.添加不同的配料:抽象方法,由子类具体实现
	abstract void addCondiment();
	//3.浸泡
	void soak() { System.out.println("第三步:豆子和配料开始浸泡3H"); }
	//4.榨汁
	void beat() { System.out.println("第四步:豆子和配料放入豆浆机榨汁"); }

	//钩子方法:决定是否需要添加配料
	boolean customerWantCondiment() {
		return true;//默认情况下是要加配料的
	}
}

// PureSoyaMilk.java
public class PureSoyaMilk extends SoyaMilk {
	@Override
	void addCondiment() {
		// 添加配料的方法 空实现 即可
	}
	@Override
	boolean customerWantCondiment() {
		return false;
	}
}

// Client.java
public class Client {
	public static void main(String[] args) {
		System.out.println("=制作纯豆浆=");
		SoyaMilk pureSoyMilk = new PureSoyaMilk();
		pureSoyMilk.make();
	}
}

4.在spring中的应用

我们先看一串代码:

在这里插入图片描述

可以看到ConfigurableApplicationContext对象的运行类型为AnnotationConfigApplicationContext

观察类图:

在这里插入图片描述

经过源码分析可以得知:

在这里插入图片描述

5.注意事项和细节

  1. 基本思想是:算法只存在于一个地方,也就是在父类中,容易修改。需要修改算法时,只要修改父类的模板方 法或者已经实现的某些步骤,子类就会继承这些修改;
  2. 实现了最大化代码复用。父类的模板方法和已实现的某些步骤会被子类继承而直接使用;
  3. 既统一了算法,也提供了很大的灵活性。父类的模板方法确保了算法的结构保持不变,同时由子类提供部分步骤的实现;
  4. 该模式的不足之处:每一个不同的实现都需要一个子类实现,导致类的个数增加,使得系统更加庞大;
  5. 一般模板方法都加上 final 关键字, 防止子类重写模板方法;
    会被子类继承而直接使用;
  6. 既统一了算法,也提供了很大的灵活性。父类的模板方法确保了算法的结构保持不变,同时由子类提供部分步骤的实现;
  7. 该模式的不足之处:每一个不同的实现都需要一个子类实现,导致类的个数增加,使得系统更加庞大;
  8. 一般模板方法都加上 final 关键字, 防止子类重写模板方法;
  9. 模板方法模式使用场景:当要完成在某个过程,该过程要执行一系列步骤 ,这一系列的步骤基本相同,但其个别步骤在实现时可能不同,通常考虑用模板方法模式来处理.

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

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

相关文章

【系统分析师】-计算题-净现值与投资回报率

1、某企业准备开发一个信息管理系统,其生存周期为5年。该系统的预计开发成本、预计的年运行/维护成本,以及预计的收益如下表所示(其中带括号的数据表示负值)。 问题1 (1)目前许多管理人员将投资的净现值作为…

Ribbon负载均衡底层原理

springcloude服务实例与服务实例之间发送请求,首先根据服务名注册到nacos,然后发送请求,nacos可以根据服务名找到对应的服务实例。 SpringCloudRibbon的底层采用了一个拦截器,拦截了openfeign发出的请求,对地址做了修…

Qt 实现不规则的部件或者窗口

1、实现不规则的部件 1.1 工程目录 1.2 界面实现 1.3 widget.cpp #include "widget.h" #include <QPixmap> #include <QBitmap> #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->set…

AI人工智能_Prompt提示词工程如何生成API接口文档

AI人工智能_Prompt提示词工程如何生成API接口文档&#xff1f;在与AI大模型的交互中&#xff0c;每当我们输入一段文字&#xff0c;无论是问题、命令还是陈述&#xff0c;这段文字就是一个Prompt。 Prompt提示词工程&#xff08;Prompt Engineering&#xff09;是一种技术或方…

【C++】—— string 类的了解与使用

【CPP】—— string类的了解与使用 1、 为什么学习string 类1.1、 C语言中的字符串1.2、 面试题中更多以 string 类出现 2、 标准库中的 string 类3、 string 的默认成员函数3.1、 string 的构造与拷贝构造3.2、 string 的赋值重载3.3、 string 的析构函数 4、 operator[ ]4.1、…

ADAS---基于检测框的单目测距方法

1.1.模型求解法方法解读&#xff1a; Yolo模型可以输出被检测物体的置信度、类别及检测框的中心点坐标(xc,yc)及宽高(w,h)等信息&#xff0c;选取车辆检测框底部的中点作为距离测量的特征点&#xff0c;其计算公式如下&#xff1a; 车辆测距示意图如下&#xff1a; 图中&#…

Zabbix之ubuntu环境下最新版zabbix-server7.0安装

一、zabbix7.0简介 Zabbix 7.0 是 Zabbix 系列中的一个主要版本&#xff0c;提供了增强的监控功能、改进的性能和扩展的可用性。Zabbix 是一个开源的企业级监控解决方案&#xff0c;用于监控服务器、虚拟机、网络设备、应用程序、服务等各类 IT 基础设施。Zabbix 7.0 继承了之前…

基于ZigBee的老人家庭监护报警设计

1 整体方案设计 本设计老人家庭监护报警系统的整体架构如图2.1所示&#xff0c;包括终端节点、协调器、上位机三个部分&#xff0c;其各个部分功能如下&#xff1a; 终端节点&#xff1a;以CC2530单片机为控制核心&#xff0c;结合心率传感器、DS18B20温度传感器、压力传感器…

大语言模型Token

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhlToken概述 Token的定义与分类 基本定义 Token是自然语言处理(NLP)和机器学习中的基本单元,它代表文本中的一个有意义的片段,如单词、短语或子词。在大型语言模型(LLM)中,Token是模型理解…

docker 介绍以及常用命令

文章目录 Docker 概述docker 概念安装 Docker核心概念Docker 镜像Docker 容器Docker 仓库 docker 与虚拟机比较 Docker 命令docker 进程相关命令镜像相关命令查看本地镜像搜索镜像拉取/推送镜像删除镜像 容器相关命令创建容器查看容器启动/终止/删除容器新建并启动容器进入容器…

day2 python学习积累

1.Python 关键字 - finally try:# 可能引发异常的代码 except 异常类型:# 异常处理代码 finally:# 无论是否发生异常都将执行的代码 try:file open("example.txt", "r")# 执行一些操作 except FileNotFoundError:print("文件不存在") finally…

你还在为去除图片背景烦恼吗?试试这两款免费神器吧!

今天想和大家聊聊在生活工作中特别实用的小工具&#xff0c;与“抠图”强相关的两款AI工具&#xff01; 说到这2个工具&#xff0c;真是忍不住要为大家强烈推荐一番&#xff01; 他们俩就是&#xff1a;PixianAI、Removerized 先说说背景去除这件事儿 无论你是设计师、摄影…

5年数据观巨变,这家公司如何在AI和大模型数据赛道遥遥领先?

过去5年&#xff0c;整个社会对于数据的观念和认知&#xff0c;发生了天翻地覆的改变。这要归功于OpenAI与预训练大语言模型&#xff08;以下简称大模型&#xff09;的问世以及横扫全球的ChatGPT。从2020年1月OpenAI发表《自然语言模型的“摩尔定律”&#xff08;Scaling Law f…

wmv怎么转换成视频mp4?简单的几种视频格式转换方法

wmv怎么转换成视频mp4&#xff1f;在数字媒体日益普及的今天&#xff0c;我们经常会遇到需要转换视频格式的情况。wmv格式&#xff0c;由微软开发&#xff0c;广泛用于Windows平台上播放视频。尽管wmv格式在Windows系统中表现优异&#xff0c;但其兼容性在其他操作系统或设备上…

关于VUE3开发频繁引入ref,reactive,computed等基础函数。

利用unplugin-auto-import插件可以避免频繁引入ref&#xff0c;reactive&#xff0c;computed等基础函数。 1.安装unplugin-auto-import依赖 npm i -D unplugin-auto-import 2.在vite.config.ts中注入依赖 效果

项目实战系列三: 家居购项目 第二部分

家居购项目 &#x1f407;servlet合并&#x1f34e;方案一: 隐藏域&#x1f34e;方案二: 反射模板设计模式动态代理 &#x1f333;显示家居&#x1f333;添加家居&#x1f349;解决重复添加&#x1f349;后端数据校验说明&#x1f349;BeanUtils自动封装Bean &#x1f333;删除…

什么是网络安全,如果做好安全

随着互联网技术的迅猛发展&#xff0c;我们的生活和工作日益依赖于网络。然而&#xff0c;这也使得网络安全问题愈发重要。网络安全不仅关乎个人隐私的保护&#xff0c;还直接影响到企业的运营安全乃至国家的信息安全。今天我们就来了解下关于网络安全&#xff0c;当前存在哪些…

初识 Embedding,为何大家都基于它搭建私人智能客服?

随着 AI 技术的发展&#xff0c;大家在日常使用过程中经常会碰到一些目前 GPT4 也无法解决的问题&#xff1a; 无法获取个人私有数据信息&#xff0c;进行智能问答无法获取最新信息&#xff0c;LLM 模型训练都是都是有截止日期的无法定制化私有的专属模型&#xff0c;从而在某…

网站开发:HTML+CSS - 表格与表单

1. 前言​​​​​​​​​​​​​​ 表格与表单在网页开发中非常重要。表格使得用户可以更简洁清晰的去浏览信息。 表单提供了一种在客户端&#xff08;浏览器&#xff09;和服务器之间进行数据交互的方式。 以下为其主要作用&#xff1a; 用户交互和数据输入&#xff1a;表…

【射频模块的基本组成以及工作原理-3D动画演示】How RF Module works?

一. 模块简介 RF是射频&#xff0c;是高频交流变化电磁波的简称。通常指的是振荡频率从30KHz到300GHz之间的电磁波。而射频模块就指的是工作在射频频率之间的模块。 二. 基本组成 RF模块指的是一组RF发射器和RF接收器。工作频率为433MHz。 1. RF transmitter RF发射器接受串…