本文主要研究一下JESA的EventRecorderjava
JESA/src/main/java/Jesa/EventRecorder.javagit
public class EventRecorder { private final ArrayList records; public EventRecorder() { this.records = new ArrayList(); } public void record(Object event) throws IllegalArgumentException { if(event == null) throw new IllegalArgumentException("The event can not be null."); this.records.add(event); } public Object[] toArray() { return this.records.toArray(); } public void clear() { this.records.clear(); } public boolean hasEvents() { return !records.isEmpty(); } }
EventRecorder定義了records,提供了record、clear、hasEvents、toArray方法
JESA/src/main/java/Jesa/InstanceEventRouter.javagithub
public interface InstanceEventRouter { <T> void configureRoute(Class<T> eventClass, Consumer<T> eventHandler) throws IllegalArgumentException; void route(Object event) throws IllegalArgumentException; }
InstanceEventRouter接口定義了configureRoute、route方法
JESA/src/main/java/Jesa/Entity.javaapp
public class Entity implements InstanceEventRouter { private final Consumer<Object> eventApplier; private final InstanceEventRouter router; public Entity(Consumer<Object> eventApplier) { if(eventApplier == null) throw new IllegalArgumentException("eventApplier cannot be null"); this.eventApplier = eventApplier; this.router = new EventRouter(); } @Override public <T> void configureRoute(Class<T> eventClass, Consumer<T> eventHandler) throws IllegalArgumentException { if(eventClass == null) throw new IllegalArgumentException("eventClass cannot be null"); if(eventHandler == null) throw new IllegalArgumentException("eventHandler cannot be null"); router.configureRoute(eventClass, eventHandler); } @Override public void route(Object event) throws IllegalArgumentException { if(event == null) throw new IllegalArgumentException("Cannot route a null event"); router.route(event); } protected void apply(Object event) { if(event == null) throw new IllegalArgumentException("Cannot apply a null event"); eventApplier.accept(event); } }
Entity實現了InstanceEventRouter接口,其configureRoute、route方法代理給了router
JESA/src/main/java/Jesa/AggregateRootEntity.javaide
public interface AggregateRootEntity extends AggregateInitializer, AggregateTrackChanges { } public interface AggregateInitializer { void initialize(Iterable<Object> events); } public interface AggregateTrackChanges { /** * Does this aggregate instance have state changes. * @return true if this aggregate instance has changes, else false. */ boolean hasChanges(); /** * Get the changes applied to this instance * @return an iterable sequence of events that have been applied. */ Object[] getChanges(); /** * Clears the events. */ void clearChanges(); }
AggregateRootEntity接口繼承了AggregateInitializer、AggregateTrackChanges接口
JESA/src/main/java/Jesa/AggregateRootEntityBase.javathis
public abstract class AggregateRootEntityBase implements AggregateRootEntity { private final EventRecorder eventRecorder; private final InstanceEventRouter eventRouter; protected AggregateRootEntityBase() { eventRecorder = new EventRecorder(); eventRouter = new EventRouter(); } public void initialize(Iterable<Object> events) { if(events == null) throw new IllegalArgumentException("Argument Events cannot be null"); if(hasChanges()) throw new IllegalArgumentException("Cannot initialize an AggregateRootEntity that already has changes."); for(Object event : events) { play(event); } } public <T> void register(Class<T> eventType, Consumer<T> handler) { if(handler == null) throw new IllegalArgumentException("Argument handler cannot be null"); eventRouter.configureRoute(eventType, handler); } public boolean hasChanges() { return eventRecorder.hasEvents(); } public Object[] getChanges() { return eventRecorder.toArray(); } public void clearChanges() { eventRecorder.clear(); } protected void applyChange(Object event) { if(event == null) throw new IllegalArgumentException("The event cannot be null."); beforeApplyChanges(event); play(event); record(event); afterApplyChanges(event); } protected void beforeApplyChanges(Object event) {} protected void afterApplyChanges(Object event) {} private void play(Object event) { eventRouter.route(event); } private void record(Object event) { eventRecorder.record(event); } }
AggregateRootEntityBase聲明實現AggregateRootEntity接口,其initialize方法遍歷events,挨個執行eventRouter.route(event);其applyChange方法前後執行beforeApplyChanges、play、record、afterApplyChanges方法
JESA/src/main/java/Jesa/Aggregate.java代理
public class Aggregate { private String identifier; private int expectedVersion; private AggregateRootEntity rootEntity; public Aggregate(String identifier, int expectedVersion, AggregateRootEntity rootEntity) { if(identifier == null) throw new IllegalArgumentException("identifier cannot be null"); if(rootEntity == null) throw new IllegalArgumentException("rootEntity cannot be null"); this.identifier = identifier; this.expectedVersion = expectedVersion; this.rootEntity = rootEntity; } public String getIdentifier() { return identifier; } public int getExpectedVersion() { return expectedVersion; } public AggregateRootEntity getRootEntity() { return rootEntity; } }
Aggregate定義了identifier、expectedVersion、rootEntity屬性
JESA的EventRecorder定義了records,提供了record、clear、hasEvents、toArray方法;InstanceEventRouter接口定義了configureRoute、route方法;Entity實現了InstanceEventRouter接口,其configureRoute、route方法代理給了router。code