DDD的优势(2)

简介: DDD的优势(2)

7.5.2 聚合根


聚合根(Aggregate Root)是DDD中的一个概念,是一种更大范围的封装,会把一组有相同生命周期、在业务上不可分割的实体和值对象放在一起,只有根实体可以对外暴露引用,这也是一种内聚性的表现。


确定聚合边界要满足固定规则(Invariant),是指在数据变化时必须保持的一致性规则,具体规则如下。


  • 根实体具有全局标识,最终负责检查规定规则。
  • 聚合内的实体具有本地标识,这些标识在Aggregate内部才是唯一的。
  • 外部对象不能引用除根Entity之外的任何内部对象。
  • 只有Aggregate的根Entity才能直接通过数据库查询获取,其他对象必须通过遍历关联来发现。
  • Aggegate内部的对象可以保持对其他Aggregate根的引用。
  • Aggregate边界内的任何对象在修改时,整个Aggregate的所有固定规则都必须满足。


仍以银行转账的例子来说明,如图7-10所示,账号(Account)是客户信息(CustomerInfo)Entity和值对象(Address)的聚合根,交易(Tansaction)是流水(Journal)的聚合根,流水是因为交易才产生的,具有相同的生命周期。


image.png


7.5.3 领域服务


有些领域中的动作是一些动词,看上去并不属于任何对象。它们代表了领域中的一个重要的行为,所以不能忽略它们或者简单地把它们合并到某个实体或者值对象中。当这样的行为从领域中被识别出来时,推荐的实践方式是将它声明成一个服务。这样的对象不再拥有内置的状态,其作用仅仅是为领域提供相应的功能。Service往往是以一个活动来命名,而不是Entity来命名。


例如在银行转账的例子中,转账(transfer)这个行为是一个非常重要的领域概念,但是它发生在两个账号之间,归属于账号Entity并不合适,因为一个账号Entity没有必要去关联它需要转账的账号Entity。在这种情况下,使用MoneyTransferDomainService就比较合适了。识别领域服务,主要看它是否满足以下3个特征。


(1)服务执行的操作代表了一个领域概念,这个领域概念无法自然地隶属于一个实体或者值对象。


(2)被执行的操作涉及领域中的其他对象。



(3)操作是无状态的。


7.5.4 领域事件


领域事件(Domain Event)是在一个特定领域由一个用户动作触发的,是发生在过去的行为产生的事件,而这个事件是系统中的其他部分或者关联系统感兴趣的。

为什么领域事件如此重要?因为在分布式环境下,很少有业务系统是单体的(Monolithic),消息作为分布式系统间耦合度最低、最健壮、最容易扩展的一种通信机制,是我们实现分布式系统互通的重要手段。关于领域事件,我们需要注意两点,分别是事件命名和事件内容。


1.事件命名


事件是表示发生在过去的事情,所以在命名上推荐使用Domain Name + 动词的过去式 + Event,这样可以更准确地表达业务语义。例如,在银行转账的例子中,对于转账成功和失败我们都需要发出事件通知,可以定义两个领域事件如下。

(1)MoneyTransferedEvent:表示转账成功发出的事件。


(2)MoneyTransferFailedEvent:表示转账失败发出的事件。


2.事件内容


事件内容在计算机术语中叫作payload,有以下两种形式。


(1)自恰(Enrichment):就是在事件的payload中尽量多放数据,这样consumer不需要回查就能处理消息,也就是自恰地处理消息。


(2)回查(Query-Back):这种方式是只在payload放置id属性,然后consumer通过回调的形式获取更多数据。这种形式会加重系统的负载,可能会引起性能问题。


7.5.5 边界上下文


领域实体的意义是有上下文的,比如同样是Apple,在水果店和苹果手机专卖店中表达出的含义就完全不一样。边界上下文(Bounded Context)的作用是限定模型的应用范围,在同一个上下文中,要保证模型在逻辑上统一,而不用考虑它是不是适用于边界之外的情况。


那么不同上下文之间的业务实体要如何实现交互呢?就像关系数据库和对象之间需要ORM一样,不同上下文之间的实体也需要映射。在DDD中,这种机制叫作上下文映射(Context Mapping),我们可以使用防腐层(Anti-Corruption)来完成映射的工作。


如图7-11所示,在我们开发的CRM系统中,商家的客户大部分是来自于ICBU网站的会员,虽然二者有很多属性都是一样的,但我们还是有必要引入防腐层来做上下文映射,主要有以下两个原因。


(1)虽然属性大部分一样,但二者的作用和行为在各自上下文中是不一样的。

(2)解耦影响,加入了防腐层之后,网站的会员变化就不会影响到CRM系统了。


image.png

相关文章
|
C语言 C++
【C语言】rand()函数(如何生成指定范围随机数)
【C语言】rand()函数(如何生成指定范围随机数)
1065 0
|
2月前
|
人工智能 安全 开发者
Claw-Eval开源:300个真实任务,端到端评测AI智能体的完成度、安全性与鲁棒性
Claw-Eval是面向自主Agent的端到端评测框架,突破“只看结果”局限,聚焦任务执行全过程——可追溯、合规、容错。基于300个人工验证的真实任务,从完成度、安全性、鲁棒性三维度评估14个前沿模型,开源数据集、排行榜及代码。
793 4
|
7月前
|
数据采集 人工智能 前端开发
爬虫与反爬技术深度解析:攻防博弈中的技术演进
本文系统解析爬虫与反爬技术的动态博弈,涵盖技术原理(静态采集→动态渲染)、反爬矩阵(基础防护→智能风控)及反反爬演进(规则对抗→AI赋能),并探讨联邦学习、大模型、隐私计算等未来趋势,强调合规生态构建。(239字)
|
人工智能 数据可视化 数据挖掘
手撕“开源版Manus”
Manus作为一款引发热议的AI智能体产品吸引了大量的关注。OpenManus作为一个开源项目,尝试复现了Manus的部分功能,可以作为一种“平替”来体验类似的技术。
|
11月前
|
Linux 网络安全 iOS开发
Metasploit Framework 6.4.90 (macOS, Linux, Windows) - 开源渗透测试框架
Metasploit Framework 6.4.90 (macOS, Linux, Windows) - 开源渗透测试框架
628 1
Metasploit Framework 6.4.90 (macOS, Linux, Windows) - 开源渗透测试框架
|
人工智能 文字识别 安全
Stirling-PDF:51.4K Star!用Docker部署私有PDF工作站,支持50多种PDF操作,从此告别在线工具
Stirling-PDF 是一款基于 Docker 的本地化 PDF 编辑工具,支持 50 多种 PDF 操作,包括合并、拆分、转换、压缩等,同时提供多语言支持和企业级功能,满足个人和企业用户的多样化需求。
1624 6
Stirling-PDF:51.4K Star!用Docker部署私有PDF工作站,支持50多种PDF操作,从此告别在线工具
|
11月前
|
JSON Java 测试技术
探索 @JsonIdentityInfo 在 Spring Boot 中的使用
Spring Boot 是一种广泛使用的框架,用于构建独立的、可用于生产的 Java 应用程序,它与 Jackson 库无缝集成以进行对象序列化和反序列化。在处理复杂的对象图时,@JsonIdentityInfo 注释在管理数据完整性和避免无限循环方面发挥着关键作用。在这篇文章中,我们将深入研究此注释的实际应用,并了解它如何显着增强您的 Spring Boot 项目。
306 0
探索 @JsonIdentityInfo 在 Spring Boot 中的使用
|
11月前
|
机器学习/深度学习 算法 算法框架/工具
256KB内存约束下的设备端训练:算法与系统协同设计——论文解读
MIT与MIT-IBM Watson AI Lab团队提出一种创新方法,在仅256KB SRAM和1MB Flash的微控制器上实现深度神经网络训练。该研究通过量化感知缩放(QAS)、稀疏层/张量更新及算子重排序等技术,将内存占用降至141KB,较传统框架减少2300倍,首次突破设备端训练的内存瓶颈,推动边缘智能发展。
705 6
|
人工智能 JSON 自然语言处理
Function AI 工作流发布:以 AI 重塑企业流程自动化
AI工作流正重塑企业自动化流程。Function AI工作流基于函数计算FC,融合LLM、Agent等技术,实现智能任务处理与自我优化,助力企业迈向智能流程自动化,提升效率,增强响应能力。
|
机器学习/深度学习 数据采集 TensorFlow
使用Python实现智能股票交易策略
使用Python实现智能股票交易策略
790 0