当前位置: 首页 > news >正文

设计模式之八:模板方法模式

泡咖啡和泡茶的共同点:

  1. 把水煮沸
  2. 沸水冲泡咖啡/茶叶
  3. 冲泡后的水倒入杯子
  4. 添加糖和牛奶/柠檬
class CoffeineBeverage
{
public:void prepareRecipe(){boilWater();brew();pourInCup();addCondiments();}private:void boilWater(){std::cout << "Boiling water" << std::endl;}virtual void brew() = 0;void pourInCup(){std::cout << "Pour in cup" << std::endl;}virtual void addCondiments() = 0;
};

在上面的代码种,prepareRecipe就是一个模板方法。

模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供实现(依赖子类提供某些或所有步骤的实现,父类拥有并保护这个算法)。

模板方法模式在一个方法中定义了一个算法的骨架,而且将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

class CaffeineBeverage
{
public:void prepareRecipe(){boilWater();brew();pourInCup();// hook 用法1// 如果算法中的某个部分是可选的// 可以用hook来控制if(hook()){addCondiments();}// hook 用法2// 让子类有机会对即将发生的,或// 刚刚发生的步骤做出反应。像是// 一种 callbackhook();}private:void boilWater(){std::cout << "Boiling water" << std::endl;}virtual void brew() = 0;void pourInCup(){std::cout << "Pour in cup" << std::endl;}virtual void addCondiments() = 0;void hook(){std::cout << "Hook" << std::endl;}
};

Hook(钩子)这个方法可以什么都不做,子类视情况决定是否覆盖它们,也可以做一些默认的事情。

钩子的存在可以让子类有能力对算法的不同点进行挂钩。

if(customerWantsCondiments())
{addCondiments();
}void addCondiments()
{// 子类可以自行决定什么时候需要添加调料return true; 
}

好莱坞原则:别调用我们,我们回调用你。此原则可以防止“依赖腐败”,避免高层和低层组件之间有明显的环状依赖,...。(高层组件可以调用低层,如CaffeineBeverage调用Coffee和Tea的方法)(由超类控制一切,当它们需要的时候,自然会去调用子类)

模板方法模式对创建框架来说很常见,由框架控制如何做事情,而框架使用者来指定框架算法中每个步骤的细节。

1. 用模板方法排序

public static void sort(Object[] a)
{Object aux[] = (Object[])a.clone();// mergeSort方法包含排序算法,依赖于compareTo方法的实现mergeSort(aux, a, 0, a.length, 0);
}private static void mergeSort(Object src[], Object desc[], int low, int high, int off)
{for (int i = low; i < high; i++){// 需要实现compareTo方法for (int j = i; j > low; && ((Comparable)dest[j-1].compareTo((Comparable)dest[j]) >0); j++){// swap是一个具体方法,已经在数组类中定义swap(dest, j, j - 1);}}return;
}

Java中的sort并不是真正定义在超类中,我们需要实现Comparable接口,实现compareTo方法。

public class Duck implement Comparable
{String name;int weight;// ......// ......// ......public int compareTo(Object object){Duck otherDucnk = (Duck)object;if(this.weight < otherDucnk.weight){return -1;}else if ( ... ) { ... }else { ... }}
}
  • 模板方法的抽象类可以定义具体方法、抽象方法和钩子。
  • 策略模式和模板方法模式都封装算法,一个用组合,一个用继承。
  • 工厂方法是模板方法的一种特殊版本。

相关文章:

设计模式之八:模板方法模式

泡咖啡和泡茶的共同点&#xff1a; 把水煮沸沸水冲泡咖啡/茶叶冲泡后的水倒入杯子添加糖和牛奶/柠檬 class CoffeineBeverage { public:void prepareRecipe(){boilWater();brew();pourInCup();addCondiments();}private:void boilWater(){std::cout << "Boiling w…...

hive可以删除单条数据吗

参考&#xff1a; hive只操作几条数据特别慢 hive可以删除单条数据吗_柳随风的技术博客_51CTO博客...

python3-Flask实现Api接口

1、&#xff1a;python3-Flask实现Api接口_flask api_Shiro to kuro的博客-CSDN博客 2、 Flask框架的web开发01&#xff08;Restful API接口规范&#xff09;_flask patch post_~须尽欢的博客-CSDN博客...

微分享 - 超实用开发日常排查问题Linux运维命令

目录 CPUCPU基本信息CPU使用情况ps 命令可用于确定哪个进程占用了 CPU 内存free 网络查看端口curl 常用命令 文件df 、du 区别磁盘使用情况文件大小文件下载压缩&解压缩查找文件查找文件内容 进程CPU 使用来升序排序内存 使用升序排序 其他常用操作系统进本信息赋予文件执行…...

Pico如何使用C/C++选择哪个I2C控制器,以及SDA和SCL针脚

本文一开始讲述了解决方案&#xff0c;后面是我做的笔记&#xff0c;用来讲述我的发现流程和探究的 Pico I2C 代码结构。 前提知识 首先要说明一点&#xff1a;Pico 有两个 I2C&#xff0c;也就是两套 SDA 和 SCL。这点你可以在针脚图中名字看出&#xff0c;比如下图的 Pin 4…...

求生之路2私人服务器开服搭建教程centos

求生之路2私人服务器开服搭建教程centos 大家好我是艾西&#xff0c;朋友想玩求生之路2(left4dead2)重回经典。Steam玩起来有时候没有那么得劲&#xff0c;于是问我有没有可能自己搭建一个玩玩。今天跟大家分享的就是求生之路2的自己用服务器搭建的一个心路历程。 &#xff0…...

Redis7之介绍(一)

1. 是什么 Redis:REmote Dictionary Server(远程字典服务器&#xff09; Remote Dictionary Server( 远程字典服务)是完全开源的&#xff0c;使用ANSIC语言编写遵守BSD协议&#xff0c;是一个高性能的Key-Value数据库提供了丰富的数据结构&#xff0c;例如String、Hash、List、…...

基于Python+djangoAI 农作物病虫害预警系统智能识别系统设计与实现(源码&教程)

1.背景 随着科技的发展&#xff0c;机器学习技术在各个领域中的应用越来越广泛。在农业领域&#xff0c;机器学习技术的应用有助于提高农作物的产量和质量&#xff0c;降低农业生产的成本。本文针对农作物健康识别问题&#xff0c;提出一种基于机器学习方法的农作健康识别系统&…...

Kotlin Flow 转换以及上下游处理

本片文章主要介绍Flow上下游处理&#xff0c;上游一个Flow使用map&#xff0c;上游两个Flow使用zip&#xff0c;上游三个Flow及以上使用combine 1、下面代码展示了upStreamFlow作为上游&#xff0c;downStreamFlow作为下游&#xff0c;通过对upStreamFlow使用map操作符函数将…...

深度学习3. 强化学习-Reinforcement learning | RL

强化学习是机器学习的一种学习方式&#xff0c;它跟监督学习、无监督学习是对应的。本文将详细介绍强化学习的基本概念、应用场景和主流的强化学习算法及分类。 目录 什么是强化学习&#xff1f; 强化学习的应用场景 强化学习的主流算法 强化学习(reinforcement learning) …...

TCP/IP网络江湖武艺传承:物理层与通信江湖的幕后

目录 〇、引言:进入现代通信技术的江湖 一、数字信号与模拟信号:传承与差异...

智慧能源管理系统助力某制造企业提高能源利用效率

随着全球能源需求不断增加和能源价格的上涨&#xff0c;企业和机构日益意识到能源管理的重要性。传统的能源管理方式不仅效率低下&#xff0c;还容易造成资源浪费和环境污染。因此&#xff0c;许多企业开始探索采用智慧能源管理系统来提高能源利用效率&#xff0c;降低能源成本…...

opencv/C++ 人脸检测

前言 本文使用的测试资源说明&#xff1a; opencv版本&#xff1a;opencv 4.6.0 人脸检测算法 Haar特征分类器 Haar特征分类器是一个XML文件&#xff0c;描述了人体各个部位的Haar特征值。包括&#xff1a;人脸、眼睛、鼻子、嘴等。 opencv 4.6.0自带的Haar特征分类器&…...

UE4/5的Custom节点:在VScode使用HLSL(新手入门用)

目录 custom节点 VSCode环境安装 将VSCode里面的代码放入Custom中 custom节点 可以看到这是一个简单的Custom节点&#xff1a; 而里面是可以填写代码的&#xff1a; 但是在这里面去写代码会发现十分的繁琐【按下enter后&#xff0c;不会换行&#xff0c;也不会自动缩进】 …...

小研究 - J2EE 应用服务器的软件老化测试研究

软件老化现象是影响软件可靠性的重要因素&#xff0c;长期运行的软件系统存在软件老化现象&#xff0c;这将影响整个业务系统的正常运行&#xff0c;给企事业单位带来无可估量的经济损失。软件老化出现的主要原因是操作系统资源消耗殆尽&#xff0c;导致应用系统的性能下降甚至…...

Tomcat和Servlet基础知识的讲解(JavaEE初阶系列16)

目录 前言&#xff1a; 1.Tomcat 1.1Tomcat是什么 1.2下载安装 2.Servlet 2.1什么是Servlet 2.2使用Servlet来编写一个“hello world” 1.2.1创建项目&#xff08;Maven&#xff09; 1.2.2引入依赖&#xff08;Servlet&#xff09; 1.2.3创建目录&#xff08;webapp&a…...

开源在大数据和分析中的角色

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

C#,《小白学程序》第四课:数学计算

1 文本格式 /// <summary> /// 《小白学程序》第四课&#xff1a;数学计算 /// 这节课超级简单&#xff0c;就是计算成绩的平均值&#xff08;平均分&#xff09; /// 这个是老师们经常做的一件事。 /// </summary> /// <param name"sender"></…...

SparkML机器学习

SparkML 机器学习: 让机器学会人的学习行为, 通过算法和数据来模拟或实现人类的学习行为&#xff0c;使之不断改善自身性能。 机器学习的步骤: 加载数据特征工程 数据筛选: 选取适合训练的特征列, 例如用户id就不适合, 因为它特性太显著.数据转化: 将字符串的数据转化数据类型…...

vue Promise 对象 等待所有异步处理完成 再继续处理

1 定义数据集合 用来搜集所有数据 let promises []; // 用来存储所有的 Promise 对象 2 promise对象 异步 返回数据 同时添加数据到promises 列表 // 依次读取列表元素的表 for (let symbol of symbolList) {let promise new Promise((resolve, reject) > { // 将请求…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...