Skip to content

Commit cf06c64

Browse files
authored
Merge branch 'iluwatar:master' into master
2 parents c189ae9 + 72da91e commit cf06c64

16 files changed

+863
-5
lines changed

Diff for: .all-contributorsrc

+29-1
Original file line numberDiff line numberDiff line change
@@ -2411,7 +2411,7 @@
24112411
"login": "saiteja55",
24122412
"name": "Saiteja Reddy",
24132413
"avatar_url": "https://avatars.githubusercontent.com/u/13088886?v=4",
2414-
"profile": "https://www.facebook.com/saiteja.reddy.94",
2414+
"profile": "https://www.linkedin.com/in/thisissaiteja/",
24152415
"contributions": [
24162416
"translation"
24172417
]
@@ -2614,6 +2614,34 @@
26142614
"contributions": [
26152615
"translation"
26162616
]
2617+
},
2618+
{
2619+
"login": "sanchitbansal10",
2620+
"name": "Sanchit Bansal",
2621+
"avatar_url": "https://avatars.githubusercontent.com/u/16536741?v=4",
2622+
"profile": "https://github.com/sanchitbansal10",
2623+
"contributions": [
2624+
"doc"
2625+
]
2626+
},
2627+
{
2628+
"login": "mm-saiful6854",
2629+
"name": "Md Saiful Islam",
2630+
"avatar_url": "https://avatars.githubusercontent.com/u/48361160?v=4",
2631+
"profile": "https://github.com/mm-saiful6854",
2632+
"contributions": [
2633+
"doc"
2634+
]
2635+
},
2636+
{
2637+
"login": "AddeusExMachina",
2638+
"name": "Antonio Addeo",
2639+
"avatar_url": "https://avatars.githubusercontent.com/u/39912670?v=4",
2640+
"profile": "https://github.com/AddeusExMachina",
2641+
"contributions": [
2642+
"doc",
2643+
"code"
2644+
]
26172645
}
26182646
],
26192647
"contributorsPerLine": 7,

Diff for: README.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=coverage)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
1111
[![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
1212
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
13-
[![All Contributors](https://img.shields.io/badge/all_contributors-287-orange.svg?style=flat-square)](#contributors-)
13+
[![All Contributors](https://img.shields.io/badge/all_contributors-289-orange.svg?style=flat-square)](#contributors-)
1414
<!-- ALL-CONTRIBUTORS-BADGE:END -->
1515

1616
<br/>
@@ -414,7 +414,7 @@ This project is licensed under the terms of the MIT license.
414414
<td align="center" valign="top" width="14.28%"><a href="https://github.com/piyush280599"><img src="https://avatars.githubusercontent.com/u/118425491?v=4?s=100" width="100px;" alt="Piyush"/><br /><sub><b>Piyush</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=piyush280599" title="Documentation">📖</a></td>
415415
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/rahulraj90/"><img src="https://avatars.githubusercontent.com/u/517415?v=4?s=100" width="100px;" alt="Rahul Raj"/><br /><sub><b>Rahul Raj</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=rahul-raj" title="Code">💻</a></td>
416416
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/bharathkalyans/"><img src="https://avatars.githubusercontent.com/u/49526472?v=4?s=100" width="100px;" alt="Bharath Kalyan S"/><br /><sub><b>Bharath Kalyan S</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=bharathkalyans" title="Code">💻</a></td>
417-
<td align="center" valign="top" width="14.28%"><a href="https://www.facebook.com/saiteja.reddy.94"><img src="https://avatars.githubusercontent.com/u/13088886?v=4?s=100" width="100px;" alt="Saiteja Reddy"/><br /><sub><b>Saiteja Reddy</b></sub></a><br /><a href="#translation-saiteja55" title="Translation">🌍</a></td>
417+
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/thisissaiteja/"><img src="https://avatars.githubusercontent.com/u/13088886?v=4?s=100" width="100px;" alt="Saiteja Reddy"/><br /><sub><b>Saiteja Reddy</b></sub></a><br /><a href="#translation-saiteja55" title="Translation">🌍</a></td>
418418
<td align="center" valign="top" width="14.28%"><a href="http://twitch.tv/clerici"><img src="https://avatars.githubusercontent.com/u/115318468?v=4?s=100" width="100px;" alt="Enrique Clerici"/><br /><sub><b>Enrique Clerici</b></sub></a><br /><a href="#translation-TheClerici" title="Translation">🌍</a></td>
419419
</tr>
420420
<tr>
@@ -444,6 +444,11 @@ This project is licensed under the terms of the MIT license.
444444
<td align="center" valign="top" width="14.28%"><a href="https://github.com/ibrahim89"><img src="https://avatars.githubusercontent.com/u/20753671?v=4?s=100" width="100px;" alt="Syyed Ibrahim Abdullah"/><br /><sub><b>Syyed Ibrahim Abdullah</b></sub></a><br /><a href="#translation-ibrahim89" title="Translation">🌍</a></td>
445445
<td align="center" valign="top" width="14.28%"><a href="https://github.com/JanisZhang"><img src="https://avatars.githubusercontent.com/u/95570096?v=4?s=100" width="100px;" alt="JiaDi Zhang"/><br /><sub><b>JiaDi Zhang</b></sub></a><br /><a href="#translation-JanisZhang" title="Translation">🌍</a></td>
446446
</tr>
447+
<tr>
448+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/sanchitbansal10"><img src="https://avatars.githubusercontent.com/u/16536741?v=4?s=100" width="100px;" alt="Sanchit Bansal"/><br /><sub><b>Sanchit Bansal</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=sanchitbansal10" title="Documentation">📖</a></td>
449+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mm-saiful6854"><img src="https://avatars.githubusercontent.com/u/48361160?v=4?s=100" width="100px;" alt="Md Saiful Islam"/><br /><sub><b>Md Saiful Islam</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=mm-saiful6854" title="Documentation">📖</a></td>
450+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/AddeusExMachina"><img src="https://avatars.githubusercontent.com/u/39912670?v=4?s=100" width="100px;" alt="Antonio Addeo"/><br /><sub><b>Antonio Addeo</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=AddeusExMachina" title="Documentation">📖</a> <a href="https://github.com/iluwatar/java-design-patterns/commits?author=AddeusExMachina" title="Code">💻</a></td>
451+
</tr>
447452
</tbody>
448453
</table>
449454

Diff for: crtp/README.md

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
title: Curiously Recurring Template Pattern
3+
language: en
4+
category: Structural
5+
tag:
6+
- Extensibility
7+
- Instantiation
8+
---
9+
10+
## Name / classification
11+
12+
Curiously Recurring Template Pattern
13+
14+
## Also known as
15+
16+
Recursive Type Bound, Recursive Generic
17+
18+
## Intent
19+
20+
Allow derived components to inherit certain functionalities from a base component that are compatible with the derived type.
21+
22+
## Explanation
23+
24+
Real-world example
25+
26+
> For a mixed martial arts promotion that is planning an event, ensuring that the fights are organized between athletes
27+
> of the same weight class is crucial. This prevents mismatches between fighters of significantly different sizes, such
28+
> as a heavyweight facing off against a bantamweight.
29+
30+
In plain words
31+
32+
> Make certain methods within a type to accept arguments specific to its subtypes.
33+
34+
Wikipedia says
35+
36+
> The curiously recurring template pattern (CRTP) is an idiom, originally in C++, in which a class X
37+
> derives from a class template instantiation using X itself as a template argument.
38+
39+
**Programmatic example**
40+
41+
Let's define the generic interface Fighter
42+
43+
```java
44+
public interface Fighter<T> {
45+
46+
void fight(T t);
47+
48+
}
49+
```
50+
51+
The MMAFighter class is used to instantiate fighters distinguished by their weight class
52+
53+
```java
54+
public class MmaFighter<T extends MmaFighter<T>> implements Fighter<T> {
55+
56+
private final String name;
57+
private final String surname;
58+
private final String nickName;
59+
private final String speciality;
60+
61+
public MmaFighter(String name, String surname, String nickName, String speciality) {
62+
this.name = name;
63+
this.surname = surname;
64+
this.nickName = nickName;
65+
this.speciality = speciality;
66+
}
67+
68+
@Override
69+
public void fight(T opponent) {
70+
LOGGER.info("{} is going to fight against {}", this, opponent);
71+
}
72+
73+
@Override
74+
public String toString() {
75+
return name + " \"" + nickName + "\" " + surname;
76+
}
77+
```
78+
79+
The followings are some subtypes of MmaFighter
80+
81+
```java
82+
class MmaBantamweightFighter extends MmaFighter<MmaBantamweightFighter> {
83+
84+
public MmaBantamweightFighter(String name, String surname, String nickName, String speciality) {
85+
super(name, surname, nickName, speciality);
86+
}
87+
88+
}
89+
90+
public class MmaHeavyweightFighter extends MmaFighter<MmaHeavyweightFighter> {
91+
92+
public MmaHeavyweightFighter(String name, String surname, String nickName, String speciality) {
93+
super(name, surname, nickName, speciality);
94+
}
95+
96+
}
97+
```
98+
99+
A fighter is allowed to fight an opponent of the same weight classes, if the opponent is of a different weight class
100+
there is an error
101+
102+
```java
103+
MmaBantamweightFighter fighter1 = new MmaBantamweightFighter("Joe", "Johnson", "The Geek", "Muay Thai");
104+
MmaBantamweightFighter fighter2 = new MmaBantamweightFighter("Ed", "Edwards", "The Problem Solver", "Judo");
105+
fighter1.fight(fighter2); // This is fine
106+
107+
MmaHeavyweightFighter fighter3 = new MmaHeavyweightFighter("Dave", "Davidson", "The Bug Smasher", "Kickboxing");
108+
MmaHeavyweightFighter fighter4 = new MmaHeavyweightFighter("Jack", "Jackson", "The Pragmatic", "Brazilian Jiu-Jitsu");
109+
fighter3.fight(fighter4); // This is fine too
110+
111+
fighter1.fight(fighter3); // This will raise a compilation error
112+
```
113+
114+
## Class diagram
115+
116+
![alt text](./etc/crtp.png "CRTP class diagram")
117+
118+
## Applicability
119+
120+
Use the Curiously Recurring Template Pattern when
121+
122+
* You have type conflicts when chaining methods in an object hierarchy
123+
* You want to use a parameterized class method that can accept subclasses of the class as arguments, allowing it to be applied to objects that inherit from the class
124+
* You want certain methods to work only with instances of the same type, such as for achieving mutual comparability.
125+
126+
## Tutorials
127+
128+
* [The NuaH Blog](https://nuah.livejournal.com/328187.html)
129+
* Yogesh Umesh Vaity answer to [What does "Recursive type bound" in Generics mean?](https://stackoverflow.com/questions/7385949/what-does-recursive-type-bound-in-generics-mean)
130+
131+
## Known uses
132+
133+
* [java.lang.Enum](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Enum.html)
134+
135+
## Credits
136+
137+
* [How do I decrypt "Enum<E extends Enum<E>>"?](http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ106)
138+
* Chapter 5 Generics, Item 30 in [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0134685997&linkCode=as2&tag=javadesignpat-20&linkId=4e349f4b3ff8c50123f8147c828e53eb)

Diff for: crtp/etc/crtp.png

120 KB
Loading

Diff for: crtp/pom.xml

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
5+
6+
The MIT License
7+
Copyright © 2014-2022 Ilkka Seppälä
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
27+
-->
28+
<project xmlns="http://maven.apache.org/POM/4.0.0"
29+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
30+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
31+
<modelVersion>4.0.0</modelVersion>
32+
<parent>
33+
<groupId>com.iluwatar</groupId>
34+
<artifactId>java-design-patterns</artifactId>
35+
<version>1.26.0-SNAPSHOT</version>
36+
</parent>
37+
<artifactId>crtp</artifactId>
38+
<dependencies>
39+
<dependency>
40+
<groupId>org.junit.jupiter</groupId>
41+
<artifactId>junit-jupiter-engine</artifactId>
42+
<scope>test</scope>
43+
</dependency>
44+
</dependencies>
45+
<build>
46+
<plugins>
47+
<plugin>
48+
<groupId>org.apache.maven.plugins</groupId>
49+
<artifactId>maven-assembly-plugin</artifactId>
50+
<executions>
51+
<execution>
52+
<configuration>
53+
<archive>
54+
<manifest>
55+
<mainClass>com.iluwatar.crtp.App</mainClass>
56+
</manifest>
57+
</archive>
58+
</configuration>
59+
</execution>
60+
</executions>
61+
</plugin>
62+
</plugins>
63+
</build>
64+
</project>

Diff for: crtp/src/main/java/crtp/App.java

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package crtp;
26+
27+
import lombok.extern.slf4j.Slf4j;
28+
29+
/**
30+
* Shows the {@link Fighter} fight method call on some implementations of {@link MmaFighter}. Note
31+
* that fighters can only fight against opponents of their same weight class.
32+
*/
33+
@Slf4j
34+
public class App {
35+
36+
/**
37+
* Program entry point.
38+
*
39+
* @param args command line args
40+
*/
41+
public static void main(String[] args) {
42+
43+
MmaBantamweightFighter fighter1 = new MmaBantamweightFighter("Joe", "Johnson", "The Geek", "Muay Thai");
44+
MmaBantamweightFighter fighter2 = new MmaBantamweightFighter("Ed", "Edwards", "The Problem Solver", "Judo");
45+
fighter1.fight(fighter2);
46+
47+
MmaHeavyweightFighter fighter3 = new MmaHeavyweightFighter("Dave", "Davidson", "The Bug Smasher", "Kickboxing");
48+
MmaHeavyweightFighter fighter4 = new MmaHeavyweightFighter("Jack", "Jackson", "The Pragmatic", "Brazilian Jiu-Jitsu");
49+
fighter3.fight(fighter4);
50+
51+
}
52+
}

Diff for: crtp/src/main/java/crtp/Fighter.java

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package crtp;
26+
27+
/**
28+
* Fighter interface.
29+
*
30+
* @param <T> The type of fighter.
31+
*/
32+
public interface Fighter<T> {
33+
34+
void fight(T t);
35+
36+
}

0 commit comments

Comments
 (0)