设计模式之八:模板方法模式
泡咖啡和泡茶的共同点:
- 把水煮沸
- 沸水冲泡咖啡/茶叶
- 冲泡后的水倒入杯子
- 添加糖和牛奶/柠檬
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 { ... }}
}
- 模板方法的抽象类可以定义具体方法、抽象方法和钩子。
- 策略模式和模板方法模式都封装算法,一个用组合,一个用继承。
- 工厂方法是模板方法的一种特殊版本。
相关文章:
设计模式之八:模板方法模式
泡咖啡和泡茶的共同点: 把水煮沸沸水冲泡咖啡/茶叶冲泡后的水倒入杯子添加糖和牛奶/柠檬 class CoffeineBeverage { public:void prepareRecipe(){boilWater();brew();pourInCup();addCondiments();}private:void boilWater(){std::cout << "Boiling w…...
hive可以删除单条数据吗
参考: hive只操作几条数据特别慢 hive可以删除单条数据吗_柳随风的技术博客_51CTO博客...
python3-Flask实现Api接口
1、:python3-Flask实现Api接口_flask api_Shiro to kuro的博客-CSDN博客 2、 Flask框架的web开发01(Restful API接口规范)_flask patch post_~须尽欢的博客-CSDN博客...
微分享 - 超实用开发日常排查问题Linux运维命令
目录 CPUCPU基本信息CPU使用情况ps 命令可用于确定哪个进程占用了 CPU 内存free 网络查看端口curl 常用命令 文件df 、du 区别磁盘使用情况文件大小文件下载压缩&解压缩查找文件查找文件内容 进程CPU 使用来升序排序内存 使用升序排序 其他常用操作系统进本信息赋予文件执行…...
Pico如何使用C/C++选择哪个I2C控制器,以及SDA和SCL针脚
本文一开始讲述了解决方案,后面是我做的笔记,用来讲述我的发现流程和探究的 Pico I2C 代码结构。 前提知识 首先要说明一点:Pico 有两个 I2C,也就是两套 SDA 和 SCL。这点你可以在针脚图中名字看出,比如下图的 Pin 4…...
求生之路2私人服务器开服搭建教程centos
求生之路2私人服务器开服搭建教程centos 大家好我是艾西,朋友想玩求生之路2(left4dead2)重回经典。Steam玩起来有时候没有那么得劲,于是问我有没有可能自己搭建一个玩玩。今天跟大家分享的就是求生之路2的自己用服务器搭建的一个心路历程。 ࿰…...
Redis7之介绍(一)
1. 是什么 Redis:REmote Dictionary Server(远程字典服务器) Remote Dictionary Server( 远程字典服务)是完全开源的,使用ANSIC语言编写遵守BSD协议,是一个高性能的Key-Value数据库提供了丰富的数据结构,例如String、Hash、List、…...
基于Python+djangoAI 农作物病虫害预警系统智能识别系统设计与实现(源码&教程)
1.背景 随着科技的发展,机器学习技术在各个领域中的应用越来越广泛。在农业领域,机器学习技术的应用有助于提高农作物的产量和质量,降低农业生产的成本。本文针对农作物健康识别问题,提出一种基于机器学习方法的农作健康识别系统&…...
Kotlin Flow 转换以及上下游处理
本片文章主要介绍Flow上下游处理,上游一个Flow使用map,上游两个Flow使用zip,上游三个Flow及以上使用combine 1、下面代码展示了upStreamFlow作为上游,downStreamFlow作为下游,通过对upStreamFlow使用map操作符函数将…...
深度学习3. 强化学习-Reinforcement learning | RL
强化学习是机器学习的一种学习方式,它跟监督学习、无监督学习是对应的。本文将详细介绍强化学习的基本概念、应用场景和主流的强化学习算法及分类。 目录 什么是强化学习? 强化学习的应用场景 强化学习的主流算法 强化学习(reinforcement learning) …...
TCP/IP网络江湖武艺传承:物理层与通信江湖的幕后
目录 〇、引言:进入现代通信技术的江湖 一、数字信号与模拟信号:传承与差异...
智慧能源管理系统助力某制造企业提高能源利用效率
随着全球能源需求不断增加和能源价格的上涨,企业和机构日益意识到能源管理的重要性。传统的能源管理方式不仅效率低下,还容易造成资源浪费和环境污染。因此,许多企业开始探索采用智慧能源管理系统来提高能源利用效率,降低能源成本…...
opencv/C++ 人脸检测
前言 本文使用的测试资源说明: opencv版本:opencv 4.6.0 人脸检测算法 Haar特征分类器 Haar特征分类器是一个XML文件,描述了人体各个部位的Haar特征值。包括:人脸、眼睛、鼻子、嘴等。 opencv 4.6.0自带的Haar特征分类器&…...
UE4/5的Custom节点:在VScode使用HLSL(新手入门用)
目录 custom节点 VSCode环境安装 将VSCode里面的代码放入Custom中 custom节点 可以看到这是一个简单的Custom节点: 而里面是可以填写代码的: 但是在这里面去写代码会发现十分的繁琐【按下enter后,不会换行,也不会自动缩进】 …...
小研究 - J2EE 应用服务器的软件老化测试研究
软件老化现象是影响软件可靠性的重要因素,长期运行的软件系统存在软件老化现象,这将影响整个业务系统的正常运行,给企事业单位带来无可估量的经济损失。软件老化出现的主要原因是操作系统资源消耗殆尽,导致应用系统的性能下降甚至…...
Tomcat和Servlet基础知识的讲解(JavaEE初阶系列16)
目录 前言: 1.Tomcat 1.1Tomcat是什么 1.2下载安装 2.Servlet 2.1什么是Servlet 2.2使用Servlet来编写一个“hello world” 1.2.1创建项目(Maven) 1.2.2引入依赖(Servlet) 1.2.3创建目录(webapp&a…...
开源在大数据和分析中的角色
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
C#,《小白学程序》第四课:数学计算
1 文本格式 /// <summary> /// 《小白学程序》第四课:数学计算 /// 这节课超级简单,就是计算成绩的平均值(平均分) /// 这个是老师们经常做的一件事。 /// </summary> /// <param name"sender"></…...
SparkML机器学习
SparkML 机器学习: 让机器学会人的学习行为, 通过算法和数据来模拟或实现人类的学习行为,使之不断改善自身性能。 机器学习的步骤: 加载数据特征工程 数据筛选: 选取适合训练的特征列, 例如用户id就不适合, 因为它特性太显著.数据转化: 将字符串的数据转化数据类型…...
vue Promise 对象 等待所有异步处理完成 再继续处理
1 定义数据集合 用来搜集所有数据 let promises []; // 用来存储所有的 Promise 对象 2 promise对象 异步 返回数据 同时添加数据到promises 列表 // 依次读取列表元素的表 for (let symbol of symbolList) {let promise new Promise((resolve, reject) > { // 将请求…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
