Created
September 10, 2018 12:23
-
-
Save erichonorez/a21c2347c2acb3f81156a549cdc0f49d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.demo; | |
import java.util.Arrays; | |
import java.util.List; | |
import java.util.UUID; | |
import lombok.Value; | |
import static io.vavr.API.$; | |
import static io.vavr.API.Case; | |
import static io.vavr.API.Match; | |
import static io.vavr.Predicates.instanceOf; | |
/** | |
* This solution uses Pattern Matching. | |
* | |
* The main advantages is that it is concise. Pattern matching can be used everywhere. | |
* The main disavantages is that the compiler does not help when new events are created (May be mitigated with unit tests). | |
*/ | |
public class EventSourcingV4 { | |
interface Event { | |
String getLoanApplicationReference(); | |
default String getVersion() { | |
return "V1"; | |
} | |
} | |
interface EventV1 extends Event { | |
@Override | |
default String getVersion() { | |
return "V1"; | |
} | |
} | |
@Value | |
static class CreatedV1 implements EventV1 { | |
private String loanApplicationReference; | |
} | |
@Value | |
static class GrantedV1 implements EventV1 { | |
private String loanApplicationReference; | |
} | |
interface EventV2 extends Event { | |
@Override | |
default String getVersion() { | |
return "V2"; | |
} | |
} | |
@Value | |
static class CreatedV2 implements EventV2 { | |
private String loanApplicationReference; | |
} | |
@Value | |
static class GrantedV2 implements EventV2 { | |
private String loanApplicationReference; | |
} | |
interface State { | |
default boolean isEmpty() { | |
return false; | |
} | |
default boolean isCreated() { | |
return false; | |
} | |
default boolean isGranted() { | |
return false; | |
} | |
} | |
static class States { | |
public static State empty() { | |
return new Empty(); | |
} | |
} | |
@Value | |
static class Empty implements State { | |
boolean isEmpty = true; | |
} | |
@Value | |
static class Created implements State { | |
String loanApplicationReference; | |
boolean isCreated = true; | |
} | |
@Value | |
static class Granted implements State { | |
String loanApplicationReference; | |
boolean isGranted = true; | |
} | |
static State apply(Event event, State state) { | |
return Match(event).of( | |
Case($(instanceOf(CreatedV1.class)), e -> applyEvent(e, state)), | |
Case($(instanceOf(GrantedV1.class)), e -> applyEvent(e, state)), | |
Case($(instanceOf(CreatedV2.class)), e -> applyEvent(e, state)), | |
Case($(instanceOf(GrantedV2.class)), e -> applyEvent(e, state)) | |
); | |
} | |
static State apply(List<Event> events, State state) { | |
return events.stream() | |
.reduce(state, (s , e) -> apply(e, s), (state1, state2) -> state2); | |
} | |
static State applyEvent(CreatedV1 event, State state) { | |
return new Created(event.getLoanApplicationReference()); | |
} | |
static State applyEvent(GrantedV1 event, State state) { | |
return new Granted(event.getLoanApplicationReference()); | |
} | |
static State applyEvent(CreatedV2 event, State state) { | |
return new Created(event.getLoanApplicationReference()); | |
} | |
static State applyEvent(GrantedV2 event, State state) { | |
return new Granted(event.getLoanApplicationReference()); | |
} | |
public static void main(String[] args) { | |
String loanApplicationReference = UUID.randomUUID().toString(); | |
State endState = apply(Arrays.asList( | |
new CreatedV1(loanApplicationReference), | |
new GrantedV1(loanApplicationReference) | |
), States.empty()); | |
System.out.println(endState.isEmpty()); | |
System.out.println(endState.isCreated()); | |
System.out.println(endState.isGranted()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment