1

本文主要研究一下JESA的EventRecorder

EventRecorder

JESA/src/main/java/Jesa/EventRecorder.java

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方法

InstanceEventRouter

JESA/src/main/java/Jesa/InstanceEventRouter.java

public interface InstanceEventRouter {
    <T> void configureRoute(Class<T> eventClass, Consumer<T> eventHandler) throws IllegalArgumentException;

    void route(Object event) throws IllegalArgumentException;
}
InstanceEventRouter接口定义了configureRoute、route方法

Entity

JESA/src/main/java/Jesa/Entity.java

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

AggregateRootEntity

JESA/src/main/java/Jesa/AggregateRootEntity.java

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接口

AggregateRootEntityBase

JESA/src/main/java/Jesa/AggregateRootEntityBase.java

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方法

Aggregate

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。

doc


codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...