当前位置: 首页 > news >正文

DDD-015:领域事件(Domain Event

DDD-015:领域事件(Domain Event)

15.1 领域事件的定义与用途

15.1.1 什么是领域事件?

【原理】
领域事件(Domain Event)是领域中已经发生的、对业务有重要意义的事实。它表示领域内发生的某件事情,通常会导致系统状态的改变或触发其他业务操作。

领域事件的核心特征:

  • 过去时态命名:OrderCreated、PaymentReceived(表示已发生)
  • 不可变性:事件一旦发生,其内容不可更改
  • 业务含义:携带业务相关的数据
  • 时效性:包含事件发生的时间
  • 因果链:一个事件可能触发其他事件

15.1.2 领域事件 vs 系统事件

【对比分析】

维度领域事件系统事件
来源业务领域技术层
命名业务术语(OrderCreated)技术术语(CacheInvalidated)
消费者业务模块技术模块
数据业务数据技术数据
目的业务解耦、流程协调技术解耦、性能优化
// ✅ 领域事件:业务含义明确publicclassOrderCreatedEventextendsDomainEvent{privatefinalOrderIdorderId;privatefinalCustomerIdcustomerId;privatefinalMoneytotalAmount;privatefinalLocalDateTimecreatedAt;}// ❌ 系统事件:技术层面publicclassCacheInvalidatedEvent{privatefinalStringcacheKey;// 这是技术事件,不是领域事件}

15.1.3 领域事件的用途

【核心用途】

用途说明示例
解耦聚合聚合间不直接调用,通过事件通信下单后扣库存
状态同步跨聚合、跨系统状态同步订单完成后更新用户积分
触发流程启动后续业务流程支付成功后触发发货
审计追踪记录业务操作历史记录所有订单状态变更
通知通知外部系统或用户订单取消后发送短信

15.2 领域事件的命名与设计

15.2.1 命名规范

【代码示例】

// ✅ 正确命名:过去时 + 业务对象 + 动作OrderCreatedEvent// 订单已创建PaymentReceivedEvent// 支付已收到OrderShippedEvent// 订单已发货CustomerUpgradedEvent// 客户已升级InventoryReservedEvent// 库存已预留// ❌ 错误命名CreateOrderEvent// 应该是过去时OrderCreateEvent// 应该是过去时OrderEvent// 太模糊,不明确发生了什么OrderStatusChangedEvent// 可以接受,但更具体更好

15.2.2 事件内容设计

【代码示例】

/** * 订单已创建事件 */publicclassOrderCreatedEventextendsDomainEvent{// ========== 事件标识 ==========privatefinalStringeventId;// 事件唯一IDprivatefinalLocalDateTimeoccurredOn;// 事件发生时间privatefinalStringeventType="OrderCreated";// 事件类型// ========== 业务数据 ==========privatefinalOrderIdorderId;// 聚合IDprivatefinalCustomerIdcustomerId;// 客户IDprivatefinalMoneytotalAmount;// 订单金额privatefinalList<OrderItemInfo>items;// 商品列表摘要// ========== 元数据 ==========privatefinalStringtriggeredBy;// 触发者privatefinalintversion=1;// 事件版本// 构造函数publicOrderCreatedEvent(OrderIdorderId,CustomerIdcustomerId,MoneytotalAmount,List<OrderItemInfo>items,StringtriggeredBy){this.eventId=UUID.randomUUID().toString();this.occurredOn=LocalDateTime.now();this.orderId=orderId;this.customerId=customerId;this.totalAmount=totalAmount;this.items=newArrayList<>(items);this.triggeredBy=triggeredBy;}// Getters(不提供Setters,保证不可变)publicStringgetEventId(){returneventId;}publicLocalDateTimegetOccurredOn(){returnoccurredOn;}publicOrderIdgetOrderId(){returnorderId;}publicCustomerIdgetCustomerId(){returncustomerId;}publicMoneygetTotalAmount(){returntotalAmount;}publicList<OrderItemInfo>getItems(){returnCollections.unmodifiableList(items);}publicStringgetTriggeredBy(){returntriggeredBy;}publicStringgetEventType(){returneventType;}publicintgetVersion(){returnversion;}}/** * 订单商品信息(值对象) */publicclassOrderItemInfoimplementsSerializable{privatefinalProductIdproductId;privatefinalStringproductName;privatefinalintquantity;// 构造函数、Getters...}

15.3 事件的发布与订阅

15.3.1 事件基类设计

【代码示例】

/** * 领域事件基类 */publicabstractclassDomainEventimplementsSerializable{privatestaticfinallongserialVersionUID=1L;// 事件唯一标识protectedStringeventId;// 事件发生时间protectedLocalDateTimeoccurredOn;// 事件类型(默认取类名)protectedStringeventType;// 事件版本(用于兼容性)protectedintversion=1;protectedDomainEvent(){this.eventId=UUID.randomUUID().toString();this.occurredOn=LocalDateTime.now();this.eventType=this.getClass().getSimpleName();}// GetterspublicStringgetEventId(){returneventId;}publicLocalDateTimegetOccurredOn(){returnoccurredOn;}publicStringgetEventType(){returneventType;}publicintgetVersion(){returnversion;}/** * 转换为JSON字符串(用于序列化) */publicStringtoJson(){try{ObjectMappermapper=newObjectMapper();mapper.registerModule(newJavaTimeModule());returnmapper.writeValueAsString(this);}catch(JsonProcessingExceptione){thrownewRuntimeException("Failed to serialize event",e);}}}/** * 领域事件发布者接口 */publicinterfaceDomainEventPublisher{/** * 发布单个事件 */voidpublish(DomainEventevent);/** * 批量发布事件 */voidpublishAll(List<DomainEvent>events);}/** * 领域事件订阅者接口 */publicinterfaceDomainEventSubscriber<TextendsDomainEvent>{/** * 处理事件 */voidhandle(Tevent);/** * 订阅的事件类型 */Class<T>subscribedToEventType();}

15.3.2 聚合根支持事件发布

【代码示例】

/** * 聚合根基类 - 支持领域事件 */publicabstractclassAggregateRoot<IDextendsIdentifier>extendsEntity<ID>{// 暂存的领域事件privatefinalList<DomainEvent>domainEvents=newArrayList<>();protectedAggregateRoot(IDid){super(id);}/** * 注册领域事件 */protectedvoidregisterEvent(DomainEventevent){this.domainEvents.add(event);}/** * 获取所有领域事件(只读) */publicList<DomainEvent>getDomainEvents(){returnCollections.unmodifiableList(domainEvents);}/** * 是否有领域事件 */publicbooleanhasDomainEvents(){return!domainEvents.isEmpty();}/** * 清空领域事件(发布后调用) */publicvoidclearDomainEvents(){this.domainEvents.clear();}}/** * 订单聚合根 - 发布事件 */publicclassOrderextendsAggregateRoot<OrderId>{privateOrderIdid;privateOrderStatusstatus;privateMoneytotalAmount;// 创建订单publicstaticOrdercreate(CustomerIdcustomerId){Orderorder=newOrder(OrderId.generate(),customerId);order.registerEvent(newOrderCreatedEvent(order.id,customerId,order.totalAmount,Collections.emptyList(),"system"));returnorder;}
http://www.jsqmd.com/news/947071/

相关文章:

  • 2026年国内口碑较好的EFT脉冲群滤波器公司,哪家更靠谱?
  • 百色市2026年最新黄金回收白银回收铂金回收门店排行榜及联系方式电话推荐 - 盛世金银回收
  • 3步实现Windows和Office永久激活:KMS智能脚本终极指南
  • mac 安装 Neo4j 图数据库
  • 手把手教你用PARL复现Atari游戏智能体:从DQN到Dueling DQN的完整训练与调参指南
  • 13000黄大年茶思屋榜文第130期——珠峰会战第七期:五大技术难题全量整理
  • 用MiniMax M2.7替代BI工程师:真实业务场景下的低代码数据查询实践
  • 基于 Harmony 6.0 应用的校园失物招领系统首页实现
  • 别再只画2D图了!用Matplotlib的Axes3D给你的K-Means聚类结果做个立体体检
  • SRAM加速LLM推理:LUT-GEMV算法与硬件架构设计
  • 蚌埠市2026年最新黄金回收白银回收铂金回收门店排行榜及联系方式电话推荐 - 盛世金银回收
  • 网卡代理商选型:从几个核心维度看清这四家差异
  • 从伺服电机对相到光栅尺校准:一台海德汉PWM21检测仪在设备大修中的全能应用清单
  • SpringBoot+Vue大学生英语学习平台源码+论文
  • Claude 3.7 vs GPT-4o真实数据管道实战对比
  • 从芯片到场景:BOS半导体以Physical AI定义车载AI Box新范式
  • mac 安装 Milvus 向量数据库
  • ssm疫情时期药物管理系统(10151)
  • 保姆级教程:手把手教你修改FFmpeg源码,让ffplay也能播H265的RTMP直播流
  • Verilog里signed和unsigned的坑,我踩了!用$signed()函数和补位技巧轻松避雷
  • 豆包2.0:一款面向真实工作流的AI交互操作系统
  • 以习惯为犁,耕十二载沃土——十二岁前必须养成的习惯体系
  • FPGA新手避坑指南:用XC7K325T配置GTX收发器,从IP核到上板调试全流程
  • 告别EV2400:用一块STM32F407开发板搞定BQ40Z50电池数据监控(电压/电量)
  • SpringBoot+Vue大学生在线考试平台源码+论文
  • 【C++11新章】一篇文章搞懂 std::initializer_list 模板类
  • GLM-5.1代码修复能力深度解析:AST引导解码与真实PR数据训练
  • 莫瑶教育AI全域课程:重构AI时代竞争力,从职场提效到商业变现的系统化成长方案 - 全国职业学校推荐官
  • Python自动化办公新思路:定时抓取通达信财务数据并关机,解放你的下班时间
  • MHmarkets迈汇平台:把服务体系做到位——细节梳理与提示整理