聊聊ddd-by-examples的DomainEvent

序 本文主要研究一下ddd-by-examples的DomainEvent
DomainEvent

public interface DomainEvent {UUID getEventId(); UUID getAggregateId(); Instant getWhen(); }

DomainEvent接口定义了getEventId、getAggregateId、getWhen方法
DomainEvents
public interface DomainEvents {void publish(DomainEvent event); default void publish(List events) { events.forEach(this::publish); } }

DomainEvents接口定义了publish方法,同时提供一个批量的publish方法
JustForwardDomainEventPublisher
@AllArgsConstructor public class JustForwardDomainEventPublisher implements DomainEvents {private final ApplicationEventPublisher applicationEventPublisher; @Override public void publish(DomainEvent event) { applicationEventPublisher.publishEvent(event); } }

JustForwardDomainEventPublisher实现了DomainEvents接口,其publish方法通过spring的ApplicationEventPublisher来发布
MeteredDomainEventPublisher
@AllArgsConstructor public class MeteredDomainEventPublisher implements DomainEvents {private static final String DOMAIN_EVENTS = "domain_events"; private static final String TAG_NAME = "name"; private final DomainEvents delegate; private final MeterRegistry metricsRegistry; @Override public void publish(DomainEvent event) { delegate.publish(event); metricsRegistry.counter(DOMAIN_EVENTS, TAG_NAME, event.getClass().getSimpleName()).increment(); } }

MeteredDomainEventPublisher实现了DomainEvents接口,其publish先执行delegate.publish(event),然后递增metrics的counter计数
StoreAndForwardDomainEventPublisher
@AllArgsConstructor public class StoreAndForwardDomainEventPublisher implements DomainEvents {private final DomainEvents eventsPublisher; private final EventsStorage eventsStorage; @Override public void publish(DomainEvent event) { eventsStorage.save(event); }@Scheduled(fixedRate = 3000L) @Transactional public void publishAllPeriodically() { List domainEvents = eventsStorage.toPublish(); domainEvents.forEach(eventsPublisher::publish); eventsStorage.published(domainEvents); } }

StoreAndForwardDomainEventPublisher实现了DomainEvents接口,其publish方法先通过eventsStorage.save(event)保存事件,之后有一个定时任务不断执行eventsStorage.toPublish()获取events,发布事件,最后执行eventsStorage.published(domainEvents)
EventsStorage
public interface EventsStorage {void save(DomainEvent event); List toPublish(); void published(List events); }

EventsStorage接口定义了save、toPublish、published方法
InMemoryEventsStorage
public class InMemoryEventsStorage implements EventsStorage {//it's not thread safe, enough for testing private final java.util.List eventList = Collections.synchronizedList(new ArrayList<>()); @Override synchronized public void save(DomainEvent event) { eventList.add(event); }@Override synchronized public List toPublish() { return List.ofAll(eventList); }@Override synchronized public void published(List events) { eventList.removeAll(events.asJava()); } }

InMemoryEventsStorage实现了EventsStorage接口,其save方法添加event到eventList,其toPublish方法返回当时的eventList,其published方法从eventList移除指定的events
小结 【聊聊ddd-by-examples的DomainEvent】ddd-by-examples定义了DomainEvent、DomainEvents接口,其中JustForwardDomainEventPublisher、MeteredDomainEventPublisher、StoreAndForwardDomainEventPublisher实现了DomainEvents接口;StoreAndForwardDomainEventPublisher借助了EventsStorage,EventsStorage接口定义了save、toPublish、published方法。
doc
  • ddd-by-examples/library

    推荐阅读