【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)

🔍目的


允许派生组件从与派生类型兼容的基本组件继承某些功能。

🔍解释


真实世界例子

对于正在策划赛事的综合格斗推广活动来说,确保在相同重量级的运动员之间组织比赛至关重要。这样可以防止体型明显不同的拳手之间的不匹配,例如重量级拳手与雏量级拳手的对决。

通俗描述

使类型中的某些方法接受特定于其子类型的参数。

维基百科

奇异递归模板模式(curiously recurring template pattern,CRTP)是C++模板编程时的一种惯用法:其中类X派生自使用X本身作为模板参数的类模板实例化。

程序实例

定义一个通用接口Fighter

public interface Fighter<T> {void fight(T t);}

定义MmaFighter类用于实例化按重量级别区分的拳手

public class MmaFighter<T extends MmaFighter<T>> implements Fighter<T> {private final String name;private final String surname;private final String nickName;private final String speciality;public MmaFighter(String name, String surname, String nickName, String speciality) {this.name = name;this.surname = surname;this.nickName = nickName;this.speciality = speciality;}@Overridepublic void fight(T opponent) {LOGGER.info("{} is going to fight against {}", this, opponent);}@Overridepublic String toString() {return name + " \"" + nickName + "\" " + surname;}

 定义MmaFighter 的一些子类型

class MmaBantamweightFighter extends MmaFighter<MmaBantamweightFighter> {public MmaBantamweightFighter(String name, String surname, String nickName, String speciality) {super(name, surname, nickName, speciality);}}public class MmaHeavyweightFighter extends MmaFighter<MmaHeavyweightFighter> {public MmaHeavyweightFighter(String name, String surname, String nickName, String speciality) {super(name, surname, nickName, speciality);}}

效果: 允许拳手与相同重量级的对手交手,如果对手是不同重量级,则会出现错误

MmaBantamweightFighter fighter1 = new MmaBantamweightFighter("Joe", "Johnson", "The Geek", "Muay Thai");
MmaBantamweightFighter fighter2 = new MmaBantamweightFighter("Ed", "Edwards", "The Problem Solver", "Judo");
fighter1.fight(fighter2); // This is fineMmaHeavyweightFighter fighter3 = new MmaHeavyweightFighter("Dave", "Davidson", "The Bug Smasher", "Kickboxing");
MmaHeavyweightFighter fighter4 = new MmaHeavyweightFighter("Jack", "Jackson", "The Pragmatic", "Brazilian Jiu-Jitsu");
fighter3.fight(fighter4); // This is fine toofighter1.fight(fighter3); // This will raise a compilation error

🔍类图


🔍适用场景


在以下情况下使用CRTP

  • 在对象层次结构中链接方法时存在类型冲突
  • 您想使用一个参数化的类方法,该方法可以接受类的子类作为参数,从而可以应用于继承自类的对象
  • 您希望某些方法仅适用于相同类型的实例,例如实现相互比较。

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

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

相关文章

生成模型 | 从 VAE 到 Diffusion Model (下)

生成模型 | 从 VAE 到 Diffusion Model &#xff08;上&#xff09;的链接请点击下方蓝色字体: 上部分主要介绍了&#xff0c;GAN, AE, VAE, VQ-VAE, DALL-E 生成模型 | 从 VAE 到 Diffusion Model &#xff08;上&#xff09; 文章目录 我们先来看一下生成模型现在的能力一&…

IT人的拖延——一放松就停不下来,耽误事?

拖延的表现 在我们的日常工作中&#xff0c;经常会面对这样一种情况&#xff1a;因为要做的Sprint ticket比较复杂或者长时间的集中注意力后&#xff0c;本来打算休息放松一下&#xff0c;刷刷剧&#xff0c;玩玩下游戏&#xff0c;但却一个不小心&#xff0c;没控制住时间&am…

IP 分片过程及偏移量计算

IP 报头中与分片相关的三个字段 1、 标识符&#xff08; ldentifier )&#xff1a;16 bit 该字段与 Flags 和 Fragment Offest 字段联合使用&#xff0c; 对较大的上层数据包进行分段&#xff08; fragment &#xff09; 操作。 路由器将一个包拆分后&#xff0c;所有拆分开的…

图解Java数组的内存分布

我们知道&#xff0c;访问数组元素要通过数组索引&#xff0c;如&#xff1a; arr[0]如果直接访问数组&#xff0c;比如&#xff1a; int[] arr1 {1}; System.out.println(arr1);会发生什么呢&#xff1f; 打印的是一串奇怪的字符串&#xff1a;[I16b98e56。 这个字符串是J…

强化训练:day11(游游的水果大礼包、 买卖股票的最好时机(二)、倒置字符串)

文章目录 前言1. 游游的水果大礼包1.1 题目描述1.2 解题思路1.3 代码实现 2. 买卖股票的最好时机(二)2.1 题目描述2.2 解题思路2.3 代码实现 3. 倒置字符串3.1 题目描述3.2 解题思路3.3 代码实现 总结 前言 1. 游游的水果大礼包   2. 买卖股票的最好时机(二)   3. 倒置字符…

数据结构初阶 栈

一. 栈的基本介绍 1. 基本概念 栈是一种线性表 是一种特殊的数据结构 栈顶&#xff1a;进行数据插入和删除操作的一端 另一端叫做栈底 压栈&#xff1a;插入数据叫做压栈 压栈的数据在栈顶 出栈&#xff1a; 栈的删除操作叫做出栈 出栈操作也是在栈顶 栈遵循一个原则 叫做…

JavaEE:Servlet创建和使用及生命周期介绍

目录 ▐ Servlet概述 ▐ Servlet的创建和使用 ▐ Servlet中方法介绍 ▐ Servlet的生命周期 ▐ Servlet概述 • Servlet是Server Applet的简称&#xff0c;意思是 用Java编写的服务器端的程序&#xff0c;Servlet被部署在服务器中&#xff0c;而服务器负责管理并调用Servle…

2024.5.21 作业 xyt

今日课堂内容&#xff1a;域套接字 TCP流式套接字 //服务器 #include <myhead.h> int main(int argc, const char *argv[]) {//1、为通信创建一个端点int sfd socket(AF_UNIX, SOCK_STREAM, 0);//参数1&#xff1a;说明使用的是ipv4通信域//参数2&#xff1a;说明使用…

HTML静态网页成品作业(HTML+CSS)——动漫海绵宝宝介绍网页(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有5个页面。 二、作品演示 三、代…

【前端笔记】记录一个能优化Echarts Geo JSON大小的网站

前端在使用Echarts等可视化图表库会不可避免遇到的问题&#xff0c;渲染地图的数据太大。 而有那么一个网站能给予这个问题一个解决方案&#xff1a;链接在此 使用方法很简单&#xff0c;首先先进入网站&#xff0c;如果进入了会是这个页面&#xff1a; 接着&#xff0c;选择一…

HCIP的学习(25)

VLAN间通讯技术 使用多臂路由的方式 ​ 路由器的物理接口默认是不识别802.1Q标签的&#xff0c;所以&#xff0c;交换机连接路由器的接口在发送数据帧时&#xff0c;应该将标签剥离。----一般常使用Access接口配置。 单臂路由 ​ 所谓的单臂路由&#xff0c;实际上试讲路由器…

【主流分布式算法总结】

文章目录 分布式常见的问题常见的分布式算法Raft算法概念Raft的实现 ZAB算法Paxos算法 分布式常见的问题 分布式场景下困扰我们的3个核心问题&#xff08;CAP&#xff09;&#xff1a;一致性、可用性、分区容错性。 1、一致性&#xff08;Consistency&#xff09;&#xff1a;…

Docker是什么?使用场景作用及Docker的安装和启动详解

目录 Docker是什么&#xff1f; Docker的发展 Docker的安装 Docker使用 Docker的运行机制 第一个Docker容器 进入Docker容器 客户机访问容器 Docker是什么&#xff1f; Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker …

记录深度学习GPU配置,下载CUDA与cuDnn

目标下载: cuda 11.0.1_451.22 win10.exe cudnn-11.0-windows-x64-v8.0.2.39.zip cuda历史版本网址 CUDA Toolkit Archive | NVIDIA Developer 自己下载过11.0.1版本 点击下载local版本,本地安装,有2个多GB,很大,我不喜欢network版本,容易掉线 cuDnn https://developer.nvi…

设置AXI主寄存器切片和AXI数据FIFO

设置AXI主寄存器切片和AXI数据FIFO 打开MHS文件&#xff0c;并为每个AXI主机设置启用寄存器切片/启用数据FIFO。到 确定正确的设置&#xff0c;使用下表中的信息搜索MHS。 进行搜索时&#xff0c;将<intf_name>替换为相关的BUS_INTERFACE名称。 例如&#xff0c;BUS_INTE…

Docker部署SpringBoot项目(jar包+Mysql)

部署Java项目 项目准备准备Java项目镜像准备配置网络 部署项目细节展示 项目准备 准备Java项目 hmall项目是一个maven聚合项目&#xff0c;使用IDEA打开hmall项目&#xff0c;查看项目结构如图&#xff1a; 我们要部署的就是其中的hm-service&#xff0c;其中的配置文件采用…

还在使用Swagger吗?ApifoxHelper插件隆重登场

目录 前言 安装Apifox Idea插件安装 插件令牌配置 获取令牌 Idea配置令牌 快速上手 同步文档 查看文档 结语&#xff1a; 前言 最近发现一款特别好用的插件&#xff0c;帮助开发者快速生成接口文档。ApifoxHelper插件实现代码零侵入&#xff0c;只需要写上相应注释即可…

K8s种的service配置

什么是service 官方的解释是:   k8s中最小的管理单元是pod&#xff1b;而service是 将运行在一个或一组 Pod 上的网络应用程序公开为网络服务的方法;   Kubernetes 中 Service 的一个关键目标是让你无需修改现有应用以使用某种服务发现机制。 你可以在 Pod 集合中运行代码…

K-独立钻石(dfs),G-邪恶铭刻(贪心)

这两题&#xff0c;都是应该赛场上A出来的。 K.独立钻石 当时一直关注点在 I. Path Planning&#xff0c;没关注榜单&#xff0c;K,也能写&#xff0c;也就是dfs,从数据范围可以看出&#xff0c;直接暴力搜索。 代码 #include<bits/stdc.h> #define int long long #d…