Skip to content

Commit 85823b4

Browse files
committed
docs: improve crtp documentation
1 parent faac96b commit 85823b4

File tree

3 files changed

+103
-62
lines changed

3 files changed

+103
-62
lines changed

cqrs/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ tag:
1010

1111
## Intent
1212

13-
CQRS aims to segregate the operations that modify the state of an application (commands) from the operations that read the state (queries). This separation allows for more flexible and optimized designs, especially in complex systems.
13+
Command Query Responsibility Segregation (CQRS) aims to segregate the operations that modify the state of an application (commands) from the operations that read the state (queries). This separation allows for more flexible and optimized designs, especially in complex systems.
1414

1515
## Explanation
1616

cqrs/src/main/java/com/iluwatar/cqrs/app/App.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
/**
3434
* CQRS : Command Query Responsibility Segregation. A pattern used to separate query services from
35-
* commands or writes services. The pattern is very simple but it has many consequences. For
35+
* commands or writes services. The pattern is very simple, but it has many consequences. For
3636
* example, it can be used to tackle down a complex domain, or to use other architectures that were
3737
* hard to implement with the classical way.
3838
*

crtp/README.md

+101-60
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,132 @@
11
---
2-
title: Curiously Recurring Template Pattern
2+
title: CRTP
33
language: en
44
category: Structural
55
tag:
6-
- Extensibility
7-
- Instantiation
6+
- Extensibility
7+
- Idiom
8+
- Instantiation
89
---
910

10-
## Name / classification
11-
12-
Curiously Recurring Template Pattern
13-
1411
## Also known as
1512

16-
Recursive Type Bound, Recursive Generic
13+
* Recursive Type Bound
14+
* Recursive Generic
15+
* Static Polymorphism
16+
* Mixin Inheritance
1717

1818
## Intent
1919

20-
Allow derived components to inherit certain functionalities from a base component that are compatible with the derived type.
20+
Curiously Recurring Template Pattern (CRTP) is used to achieve a form of static polymorphism by having a class template derive from a template instantiation of its own class, allowing method overriding and polymorphic behavior at compile time rather than at runtime.
2121

2222
## Explanation
2323

2424
Real-world example
2525

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.
26+
> For a mixed martial arts promotion that is planning an event, ensuring that the fights are organized between athletes of the same weight class is crucial. This prevents mismatches between fighters of significantly different sizes, such as a heavyweight facing off against a bantamweight.
2927
3028
In plain words
3129

3230
> Make certain methods within a type to accept arguments specific to its subtypes.
3331
3432
Wikipedia says
3533

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.
34+
> The curiously recurring template pattern (CRTP) is an idiom, originally in C++, in which a class X derives from a class template instantiation using X itself as a template argument.
3835
3936
**Programmatic example**
4037

41-
Let's define the generic interface Fighter
38+
Let's define the generic interface Fighter.
4239

4340
```java
4441
public interface Fighter<T> {
4542

46-
void fight(T t);
43+
void fight(T t);
4744

4845
}
4946
```
5047

51-
The MMAFighter class is used to instantiate fighters distinguished by their weight class
48+
The MMAFighter class is used to instantiate fighters distinguished by their weight class.
5249

5350
```java
5451
public class MmaFighter<T extends MmaFighter<T>> implements Fighter<T> {
5552

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-
}
53+
private final String
54+
name;
55+
private final String
56+
surname;
57+
private final String
58+
nickName;
59+
private final String
60+
speciality;
61+
62+
public MmaFighter(
63+
String name,
64+
String surname,
65+
String nickName,
66+
String speciality) {
67+
this.name =
68+
name;
69+
this.surname =
70+
surname;
71+
this.nickName =
72+
nickName;
73+
this.speciality =
74+
speciality;
75+
}
76+
77+
@Override
78+
public void fight(
79+
T opponent) {
80+
LOGGER.info(
81+
"{} is going to fight against {}",
82+
this,
83+
opponent);
84+
}
85+
86+
@Override
87+
public String toString() {
88+
return
89+
name +
90+
" \"" +
91+
nickName +
92+
"\" " +
93+
surname;
94+
}
95+
}
7796
```
7897

79-
The followings are some subtypes of MmaFighter
98+
The followings are some subtypes of MmaFighter.
8099

81100
```java
82101
class MmaBantamweightFighter extends MmaFighter<MmaBantamweightFighter> {
83102

84-
public MmaBantamweightFighter(String name, String surname, String nickName, String speciality) {
85-
super(name, surname, nickName, speciality);
86-
}
103+
public MmaBantamweightFighter(String name, String surname, String nickName, String speciality) {
104+
super(name, surname, nickName, speciality);
105+
}
87106

88107
}
89108

90109
public class MmaHeavyweightFighter extends MmaFighter<MmaHeavyweightFighter> {
91110

92-
public MmaHeavyweightFighter(String name, String surname, String nickName, String speciality) {
93-
super(name, surname, nickName, speciality);
94-
}
111+
public MmaHeavyweightFighter(String name, String surname, String nickName, String speciality) {
112+
super(name, surname, nickName, speciality);
113+
}
95114

96115
}
97116
```
98117

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
118+
A fighter is allowed to fight an opponent of the same weight classes. If the opponent is of a different weight class, an error is raised.
101119

102120
```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
121+
MmaBantamweightFighter fighter1=new MmaBantamweightFighter("Joe","Johnson","The Geek","Muay Thai");
122+
MmaBantamweightFighter fighter2=new MmaBantamweightFighter("Ed","Edwards","The Problem Solver","Judo");
123+
fighter1.fight(fighter2); // This is fine
106124

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
125+
MmaHeavyweightFighter fighter3=new MmaHeavyweightFighter("Dave","Davidson","The Bug Smasher","Kickboxing");
126+
MmaHeavyweightFighter fighter4=new MmaHeavyweightFighter("Jack","Jackson","The Pragmatic","Brazilian Jiu-Jitsu");
127+
fighter3.fight(fighter4); // This is fine too
110128

111-
fighter1.fight(fighter3); // This will raise a compilation error
129+
fighter1.fight(fighter3); // This will raise a compilation error
112130
```
113131

114132
## Class diagram
@@ -117,22 +135,45 @@ fighter1.fight(fighter3); // This will raise a compilation error
117135

118136
## Applicability
119137

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
138+
* When you need to extend the functionality of a class through inheritance but prefer compile-time polymorphism to runtime polymorphism for efficiency reasons.
139+
* When you want to avoid the overhead of virtual functions but still achieve polymorphic behavior.
140+
* In template metaprogramming to provide implementations of functions or policies that can be selected at compile time.
141+
* You have type conflicts when chaining methods in an object hierarchy.
142+
* 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.
124143
* You want certain methods to work only with instances of the same type, such as for achieving mutual comparability.
125144

126145
## Tutorials
127146

128147
* [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)
148+
* Yogesh Umesh Vaity's answer to [What does "Recursive type bound" in Generics mean?](https://stackoverflow.com/questions/7385949/what-does-recursive-type-bound-in-generics-mean)
130149

131150
## Known uses
132151

152+
* Implementing compile-time polymorphic interfaces in template libraries.
153+
* Enhancing code reuse in libraries where performance is critical, like in mathematical computations, embedded systems, and real-time processing applications.
133154
* [java.lang.Enum](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Enum.html)
134155

156+
## Consequences
157+
158+
Benefits:
159+
160+
* Elimination of virtual function call overhead, enhancing performance.
161+
* Safe reuse of the base class code without the risks associated with multiple inheritances.
162+
* Greater flexibility and extensibility in compile-time polymorphism scenarios.
163+
164+
Trade-offs:
165+
166+
* Increased complexity in understanding and debugging due to the interplay of templates and inheritance.
167+
* Can lead to code bloat because each instantiation of a template results in a new class.
168+
* Less flexibility compared to runtime polymorphism as the behavior must be determined entirely at compile time.
169+
170+
## Related Patterns
171+
172+
* [Factory Method](https://java-design-patterns.com/patterns/factory-method/): Can be used in conjunction with CRTP to instantiate derived classes without knowing their specific types.
173+
* [Strategy](https://java-design-patterns.com/patterns/strategy/): CRTP can implement compile-time strategy selection.
174+
* [Template Method](https://java-design-patterns.com/patterns/template-method/): Similar in structure but differs in that CRTP achieves behavior variation through compile-time polymorphism.
175+
135176
## Credits
136177

178+
* [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)
137179
* [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)

0 commit comments

Comments
 (0)