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

简介: 该文介绍了一种C++的编程技巧——奇异递归模板模式(CRTP),旨在让派生组件能继承基本组件的特定功能。通过示例展示了如何创建一个`Fighter`接口和`MmaFighter`类,其中`MmaFighter`及其子类如`MmaBantamweightFighter`和`MmaHeavyweightFighter`强制类型安全,确保相同重量级的拳手之间才能进行比赛。这种设计避免了不同重量级拳手间的错误匹配,编译时会报错。CRTP适用于处理类型冲突、参数化类方法和限制方法只对相同类型实例生效的情况。

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

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

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

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

程序实例
定义一个通用接口Fighter

public interface Fighter {

void fight(T t);

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

public class MmaFighter> implements Fighter {

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;
}

@Override
public void fight(T opponent) {
LOGGER.info("{} is going to fight against {}", this, opponent);
}

@Override
public String toString() {
return name + " \"" + nickName + "\" " + surname;
}

定义MmaFighter 的一些子类型

class MmaBantamweightFighter extends MmaFighter {

public MmaBantamweightFighter(String name, String surname, String nickName, String speciality) {
super(name, surname, nickName, speciality);
}

}

public class MmaHeavyweightFighter extends MmaFighter {

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 fine

MmaHeavyweightFighter 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 too

fighter1.fight(fighter3); // This will raise a compilation error
🔍类图
image.png

🔍适用场景
在以下情况下使用CRTP

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

相关文章
|
1月前
|
设计模式 数据采集 算法
【设计模式】【行为型模式】模板方法模式(Template Method)
一、入门 1.1、什么是模板方法模式? 模板模式(Template Method Pattern)是一种行为设计模式,它定义了一个算法的框架,并允许子类在不改变算法结构的情况下重新定义算法的某些步骤。
73 13
|
8月前
|
搜索推荐 Java 数据库连接
Java|在 IDEA 里自动生成 MyBatis 模板代码
基于 MyBatis 开发的项目,新增数据库表以后,总是需要编写对应的 Entity、Mapper 和 Service 等等 Class 的代码,这些都是重复的工作,我们可以想一些办法来自动生成这些代码。
126 6
|
8月前
|
算法 Java Linux
java制作海报四:java BufferedImage 转 InputStream 上传至OSS。png 图片合成到模板(另一个图片)上时,透明部分变成了黑色
这篇文章主要介绍了如何将Java中的BufferedImage对象转换为InputStream以上传至OSS,并解决了png图片合成时透明部分变黑的问题。
351 1
|
8月前
|
Java
Java PDF模板生成PDF
Java PDF模板生成PDF
167 1
|
8月前
|
小程序
java--微信小程序发送模板消息
java--微信小程序发送模板消息
290 0
|
10月前
|
小程序 Java
【aspose-words】Aspose.Words for Java模板语法详细剖析
本文通过详细分析Aspose.Words for Java模板语法,介绍了使用条件块、变量和动态合并表格单元格三个常用模板标签,并结合实际案例进行演示。通过这三个标签的实操,帮助读者更好地掌握Aspose.Words的使用技巧。此外,还提供了官方文档链接以便进一步学习。
268 0
【aspose-words】Aspose.Words for Java模板语法详细剖析
|
9月前
|
Java Apache Maven
Java中使用poi+poi-tl实现根据模板导出word文档
这个过程不仅简化了文档生成的工作,而且保证了生成文档的一致性与准确性,特别适合于那些需要生成大量文档的自动化场景。通过以上步骤,Java开发人员可以实现高效、可靠的Word文档导出功能。
2486 0
|
10月前
|
前端开发 开发者 开发框架
JSF与Bootstrap,打造梦幻响应式网页!让你的应用跨设备,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,响应式设计至关重要,以确保不同设备上的良好用户体验。本文探讨了JSF(JavaServer Faces)与Bootstrap框架的结合使用,展示了如何构建响应式网页。JSF是一个基于Java的Web应用框架,提供丰富的UI组件和表单处理功能;而Bootstrap则是一个基于HTML、CSS和JavaScript的前端框架,专注于实现响应式设计。通过结合两者的优势,开发者能够更便捷地创建自适应布局,提升Web应用体验。然而,这种组合也有其局限性,如JSF组件库较小和较高的学习成本等,因此在选择开发框架时需综合考虑具体需求和应用场景。
106 0