专栏首页码匠的流水账聊聊ddd-by-examples的DomainEvent

聊聊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<DomainEvent> 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<DomainEvent> 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<DomainEvent> toPublish();

    void published(List<DomainEvent> events);
}

EventsStorage接口定义了save、toPublish、published方法

InMemoryEventsStorage

public class InMemoryEventsStorage implements EventsStorage {

    //it's not thread safe, enough for testing
    private final java.util.List<DomainEvent> eventList = Collections.synchronizedList(new ArrayList<>());

    @Override
    synchronized public void save(DomainEvent event) {
        eventList.add(event);
    }

    @Override
    synchronized public List<DomainEvent> toPublish() {
        return List.ofAll(eventList);
    }

    @Override
    synchronized public void published(List<DomainEvent> events) {
        eventList.removeAll(events.asJava());
    }
}

InMemoryEventsStorage实现了EventsStorage接口,其save方法添加event到eventList,其toPublish方法返回当时的eventList,其published方法从eventList移除指定的events

小结

ddd-by-examples定义了DomainEvent、DomainEvents接口,其中JustForwardDomainEventPublisher、MeteredDomainEventPublisher、StoreAndForwardDomainEventPublisher实现了DomainEvents接口;StoreAndForwardDomainEventPublisher借助了EventsStorage,EventsStorage接口定义了save、toPublish、published方法。

doc

  • ddd-by-examples/library

本文分享自微信公众号 - 码匠的流水账(geek_luandun),作者:码匠乱炖

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-04-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊聊ddd-by-examples的DomainEvent

    ddd-by-examples定义了DomainEvent、DomainEvents接口,其中JustForwardDomainEventPublisher、M...

    codecraft
  • 聊聊cheddar的DomainEvent

    Cheddar/cheddar/cheddar-domain/src/main/java/com/clicktravel/cheddar/domain/even...

    codecraft
  • 聊聊cheddar的DomainEvent

    Cheddar/cheddar/cheddar-domain/src/main/java/com/clicktravel/cheddar/domain/even...

    codecraft
  • 聊聊DDD的分层架构

    在《领域驱动设计——软件核心复杂性应对之道》一书中Eric Evans将应用架构分为以下层级:

    心平气和
  • 实现领域事件

    当你的系统或者业务变得日益复杂时, DDD的模式是一种非常值得尝试的架构模式。 DDD让你更加关注于你的业务领域,思考你的业务模型,帮组你理清繁杂的业务关系。我...

    程序猿DD
  • 聊聊golang的DDD项目结构

    DDD一般分为interfaces、application、domain、infrastructure这几层;其中domain层不依赖其他层,它定义reposi...

    codecraft
  • 聊聊golang的DDD项目结构

    DDD一般分为interfaces、application、domain、infrastructure这几层;其中domain层不依赖其他层,它定义reposi...

    codecraft
  • 再谈领域事件

    我以前写过一篇关于领域事件的文章——《实现领域事件》,随着在项目中深入的使用DDD架构,我对领域事件有了新的认识。尤其是采用领域事件来解耦代码这种方式对项目的发...

    程序猿DD
  • 《Netty+JavaFx实战:仿桌面版微信聊天》代码开源、上云部署、视频讲解!

    视频:https://mp.weixin.qq.com/s/OmXCY4fTfDpkvjlg5ME0ZA

    小傅哥
  • 《Netty + JavaFx 实战:仿桌面版微信聊天》

    走过了一个漫长的假期,从年假的第一天开始因为不能但又不能让自己太闲,就开始研究将所学的Netty技术实践一把,以此来巩固不同类型的技术栈在实际业务中的使用。那么...

    小傅哥
  • 面试官问:如何快速开发一个类似微信的聊天系统?

    去年我们公司要我去面试一位候选人,当时刚好我接手了公司的 IM 系统,借这个机会,就问了候选人这个问题:如何快速开发一个类似微信的聊天系统?

    用户1737318
  • 一文一点 | 你认为什么是DDD设计方法的基石

    所有的软件最终是要解决用户问题的,而软件的落地最终是要靠一行行的代码垒起来的,那么这个时候从识别出用户问题到代码实现之间就需要一种过度,而架构设计就是这种过度的...

    王新栋
  • 记一次在.NET成长之路上的下午茶

    在2017年2月25日我和李海国有幸与罗阳铭、朱永光两位大哥喝了一次下午茶。熟悉ABP框架的朋友呢知道阳铭远在上海,所以个人很是珍惜这次机会。朱永光大哥是微软M...

    角落的白板报
  • Qt项目网络聊天室设计

    3. 服务器接收到某个客户端的请求以及发送信息,经服务器发给其它客户端 最终实现一个共享聊天内容的聊天室!

    DeROy
  • 自然语言处理(NLP)相关

    结巴分词使用 中文分词之结巴分词~~~附使用场景+demo(net) jieba分词、自定义词典提取高频词、词性标注及获取词的位置 jieba分词增加自定义词...

    致Great
  • 为何我用DDD重构了才刚上线的新项目?

    很多人初次接触DDD会有些反感,特别是对DO、DTO、PO这些对象转来转去反感,也有人质疑这样做影响性能。

    Java艺术
  • 模仿微信,开发一个分布式IM(即时通信)系统!

    是不是感觉很多资料,点收藏起来爽、看视频时候嗨、读文章当时会,只要过了那个劲,就完了,根本不记得这里面都讲了啥。时间浪费了,东西还没学到手,这是为啥?

    小傅哥
  • 我们团队是如何落地DDD的(1)

    DDD领域驱动设计,起源于2004年著名建模专家Eric Evans发表的他最具影响力的著名书籍:Domain-Driven Design –Tackling ...

    方丈的寺院
  • DDD理论学习系列(3)-- 限界上下文

    1. 引言 限界上下文可以拆分为两个词,限界和上下文。 限界:是指一个界限,具体的某一个范围。 上下文:个人理解就是语境。 比如我们常说的段子: “我想静...

    圣杰

扫码关注云+社区

领取腾讯云代金券