Skip to content

Instantly share code, notes, and snippets.

@erichonorez
Created September 10, 2018 12:22
Show Gist options
  • Save erichonorez/bdcf5a08bcae1105d88cf0a0b958ebb1 to your computer and use it in GitHub Desktop.
Save erichonorez/bdcf5a08bcae1105d88cf0a0b958ebb1 to your computer and use it in GitHub Desktop.
package com.example.demo;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;
import lombok.AllArgsConstructor;
import lombok.Value;
/**
* This solution is another implementation of EventSourcing. In this implementation each {@link Event} knows how to apply itself on a state. It results in code simplification to apply event on state.
*
* <ol>
* <li>7 types for events</li>
* </ol>
*
* The main advantages is that it is still safe from a compilation POV. There is less code be Visitor are required for other use cases.
* The drawback is that if we use event is a client libs, domain code leaks.
*/
public class EventSourcingV3 {
interface Event {
String getLoanApplicationReference();
Data apply(Data s);
default String getVersion() {
return "V1";
}
}
interface EventV1 extends Event {
@Override
default String getVersion() {
return "V1";
}
}
@Value
static class CreatedV1 implements EventV1 {
private String loanApplicationReference;
@Override
public Data apply(Data s) {
return s;
}
}
@Value
static class GrantedV1 implements EventV1 {
private String loanApplicationReference;
@Override
public Data apply(Data s) {
return new Data(true);
}
}
interface EventV2 extends Event {
@Override
default String getVersion() {
return "V2";
}
}
@Value
static class CreatedV2 implements EventV2 {
private String loanApplicationReference;
@Override
public Data apply(Data s) {
return s;
}
}
@Value
static class GrantedV2 implements EventV2 {
private String loanApplicationReference;
@Override
public Data apply(Data s) {
new Data(true);
return s;
}
}
static Data apply(List<Event> es, Data s) {
return es.stream()
.reduce(s, (state, event) -> event.apply(s), (s1, s2) -> s2);
}
@Value
static class Data {
boolean isGranted;
}
public static void main(String[] args) {
String loanApplicationReference = UUID.randomUUID().toString();
Data initialState = new Data(false);
Data endState = apply(Arrays.asList(
new CreatedV1(loanApplicationReference),
new GrantedV1(loanApplicationReference)
), initialState);
System.out.println(endState.isGranted());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment