Skip to content

Commit

Permalink
use Java 21 pattern matching
Browse files Browse the repository at this point in the history
  • Loading branch information
forax committed Sep 27, 2023
1 parent 9b82fe9 commit 2fc5438
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 12 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Design Patterns Reloaded
Implementation of some design patterns in Java 17,
Implementation of some design patterns in Java 21,
some of them are from the GoF, others are the one you usually see in programs.

Like most of the GoF patterns, the implementations use delegation instead of inheritance,
Expand All @@ -21,7 +21,7 @@ but also emphasis immutability when necessary.
- [state](src/main/java/state) delegates API implementation to an internal state object
- [template_method](src/main/java/templatemethod) define a behavior with a generic part and a specific part
- [typing](src/main/java/typing), 3 kinds of relations between a static type and a runtime class
- [visitor](src/main/java/visitor), specify operations on a hierarchy of types outside that hierarchy
- [visitor / pattern matching](src/main/java/visitor), specify operations on a hierarchy of types outside that hierarchy


## Old materials
Expand Down
20 changes: 11 additions & 9 deletions src/main/java/visitor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,27 +166,29 @@ that takes an `Object`. This is done by done a dynamic cast (the method referenc

## Pattern matching

The visitor pattern is a way to a switch on a hierarchy of classes, starting with Java 17, as a preview feature
we can now do a switch on an interface.
The visitor pattern is a way to a switch on a hierarchy of classes, starting with Java 21 we can now do a switch
on a sealed interface.

```java
static int count(Vehicle vehicle) {
return switch(vehicle) {
return switch (vehicle) {
case Car car -> 1;
case CarHauler carHauler -> 1 + carHauler.cars().stream().mapToInt(car -> count(car)).sum());
case CarHauler carHauler -> 1 + carHauler.cars().stream().mapToInt(car -> count(car)).sum();
};
}
```

Like with the double dispatch, this requires the hierarchy to be sealed otherwise the compiler do not know
if the cases cover all possible subtypes.

In the future, Java will allow to access the components of the matched types without breaking the encapsulation
Java also allow to match all the record components using a record pattern
```java
static int count(Vehicle vehicle) { /* provisional syntax */
return switch(vehicle) {
case Car _ -> 1;
case CarHauler(var cars) -> 1 + cars.stream().mapToInt(car -> count(car)).sum());
static int count(Vehicle vehicle) {
return switch (vehicle) {
case Car() -> 1;
case CarHauler(List<Car> cars) -> 1 + cars.stream().mapToInt(car -> count(car)).sum();
};
}
```

In the future, this capability will be extended to match not only records but also classes
2 changes: 1 addition & 1 deletion src/main/java/visitor/visitor2.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.function.Function;

public interface visitor2 {
/*not sealed*/ interface Vehicle { }
interface Vehicle { }
record Car() implements Vehicle { }
record CarHauler(List<Car> cars) implements Vehicle {}

Expand Down
22 changes: 22 additions & 0 deletions src/main/java/visitor/visitor3.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package visitor;

import java.util.List;

public interface visitor3 {
sealed interface Vehicle { }
record Car() implements Vehicle { }
record CarHauler(List<Car> cars) implements Vehicle {}

static int count(Vehicle vehicle) {
return switch (vehicle) {
case Car() -> 1;
case CarHauler(List<Car> cars) -> 1 + cars.stream().mapToInt(car -> count(car)).sum();
};
}

static void main(String[] args) {
var vehicle = new CarHauler(List.of(new Car(), new Car()));
var count = count(vehicle);
System.out.println(count);
}
}

0 comments on commit 2fc5438

Please sign in to comment.