领域模型:聚合、聚合根详解

  聚合和聚合根是领域模型里面很重要的一个概念,其实我们在从真实世界对业务对象进行识别和概念建模的时候,关注的就是聚合根,这才是我们真正要管理的业务对象。一个对象可能有多个层次,也可能有多个子实体,但是这些子实体都不可能孤立存在,它们必须依附于一个聚合根存在,它们和根节点具有同样的生命周期。

  如果一个客户消亡,客户联系方式,客户的多张银行账户信息将不再有任何意义。如果一张采购订单头消失,那么采购订单明细没有任何存在的意义。客户,采购订单,发票这些从真实业务中转化过来的业务对象才是真正的领域核心对象。这些对象可能在领域建模的时候会分解到多个Entity或Value Object,但是一定要意识到实际的聚合在哪里?我们真正关注的业务对象实体究竟有哪些?

  为什么如此强调领域模型,强调聚合根的概念,因此我们在关注领域模型的时候将有助于我们打破原有的关系型数据库的思维模式,转化为对象和领域的思维模式。可以看到领域建模和聚合根的思路正是既适合于关系型数据库,也适合NoSql数据库的建模思路。因为在NoSQL持久化的时候,我们看到采购订单就是一个对象,其它明细和关联信息都是这个对象下的子实体信息,采购订单应该作为一个对象整体进行查询和存储,我们并不关系NoSQL会如何去存储这个对象。让我们正在关注领域对象,而不是去关心如何持久化。

  聚合Aggregate就是一组相关对象的集合,我们把它作为数据修改和访问的单元。每个聚合都会有一个聚合根和聚合的边界Boundary,边界定义了在一个聚合里面内部应该有哪些实体,哪些子实体对象。定义边界的原因是我们期望对一个聚合的访问是通过聚合根点进行的,聚合里面的子实体对外界是完全封闭的。对于外部对象不应该去访问到一个聚合边界里面的子实体。

  在一些场景下,对于一个聚合的访问,我们往往只需要查询到头信息,而不关心具体的子实体信息,这个有点类似于传统O/R Mapping里面的惰性加载。在这里也必须要考虑到。在实现和设计聚合的时候,需要考虑到这种场景,即根据需要来加载一个完整聚合中的实体和子实体,以满足性能的需要。如何对应关系型数据库,对一个聚合实际的新增变更处理则可能涉及到多个数据表的多次操作,而这已经是仓储接口和仓储实现需要考虑的问题。现在对一个聚合的一次操作一定应该在一个完整的事务里面,以保障实际的事务完整性要求。

  按实际对象分析思路,在领域模型中的领域对象分析应该按照从顶向下的思路进行展开,如果这样的话首先识别到的就是聚合根对象,然后再考虑对聚合根对象进行展开,在聚合根对象的展开过程中进一步细化子实体之间的关联和依赖关系。

转自: https://www.cnblogs.com/lycsmzl/p/6637522.html

领域驱动设计(DDD:Domain-Driven Design)

  Eric Evans的“Domain-Driven Design领域驱动设计”简称DDD,Evans DDD是一套综合软件系统分析和设计的面向对象建模方法,本站Jdon.com是国内公开最早讨论DDD网站之一,可订阅DDD专题。初学者学习DDD可从研究本站Jdon框架的DDD应用源码开始,戳这里开始。

  过去系统分析和系统设计都是分离的,正如我们国家“系统分析师” 和“系统设计师” 两种职称考试一样,这样割裂的结果导致,需求分析的结果无法直接进行设计编程,而能够进行编程运行的代码却扭曲需求,导致客户运行软件后才发现很多功能不是自己想要的,而且软件不能快速跟随需求变化。

  DDD则打破了这种隔阂,提出了领域模型概念,统一了分析和设计编程,使得软件能够更灵活快速跟随需求变化。见下面DDD与传统CRUD或过程脚本或者面向数据表等在开发效率上比较:

  服务器后端发展三个阶段:

  1. UI+DataBase的两层架构,这种面向数据库的架构(上图table module )没有灵活性。
  2. UI+Service+DataBase的多层SOA架构,这种服务+表模型的架构易使服务变得囊肿,难于维护拓展,伸缩性能差,见这里讨论或Spring Web 应用的最大败笔.
  3. DDD+SOA的事件驱动的CQRS读写分离架构,应付复杂业务逻辑,以聚合模型替代数据表模型,以并发的事件驱动替代串联的消息驱动。真正实现以业务实体为核心的灵活拓展。

  DDD革命性在于:领域模型准确反映了业务语言,而传统J2EE或Spring+Hibernate等事务性编程模型只关心数据,这些数据对象除了简单setter/getter方法外,没有任何业务方法,被比喻成失血模型,那么领域模型这种带有业务方法的充血模型到底好在哪里?

  以比赛Match为案例,比赛有“开始”和“结束”等业务行为,但是传统经典的方式是将“开始”和“结束”行为放在比赛的服务Service中,而不是放在比赛对象本身之中。我们不能因为用了计算机,用了数据库,用了框架,业务模型反而被技术框架给绑架,就像人虽然是由母亲生的,但是人的吃喝拉撒母亲不能替代,更不能以母爱名义肢解人的正常职责行为,如果是这样,这个人就是被母爱绑架了。

  提倡充血模型,实际就是让过去被肢解被黑crack的业务模型回归正常,当然这也会被一些先入为主或被洗过脑的程序员看成反而不正常,这更是极大可悲之处。看到领域模型代码,就看到业务需求,没有翻译没有转换,保证软件真正实现“拷贝不走样”。

  DDD最大的好处是:接触到需求第一步就是考虑领域模型,而不是将其切割成数据和行为,然后数据用数据库实现,行为使用服务实现,最后造成需求的首肢分离。DDD让你首先考虑的是业务语言,而不是数据。重点不同导致编程世界观不同。

  DDD是解决复杂中大型软件的一套行之有效方式,在国外已经成为主流。DDD认为很多原因造成软件的复杂性,我们不可能避免这些复杂性,能做的是对复杂的问题进行控制。而一个好的领域模型是控制复杂问题的关键。领域模型的价值在于提供一种通用的语言,使得领域专家和软件技术人员联系在一起,沟通无歧义。

  DDD在软件生产流程中定位i如下图,DDD落地实现离不开in-memory缓存、 CQRS、 DCI、 EDA或Event Source几大大相关领域。

转自: https://www.jdon.com/ddd.html

领域模型DDD与聚合根相关推荐

  1. DDD单根 聚合根 实体 值对象

    前言 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity in the Heart of Software (领域驱动设计),简称E ...

  2. DDD:聚合根的批量删除是不是可以批量发送请求

    背景 搞了近五年的系统开发,总是抱着一种思维模式,用户的一个操作对应一个请求和一个事务,比如:用户选择了N条记录,我就会向服务器发生一个请求,服务器在一个事务中进行处理.前几天在群里一个前辈反问:批量 ...

  3. DDD - 聚合与聚合根_如何理解 Respository与DAO

    文章目录 Pre Question 如何理解 聚合和聚合根 利用聚合解决业务上的原子性操作 如何确定聚合和聚合根 Respository VS DAO Pre 通常情况,我们都会面临这样的一个问题: ...

  4. 1.DDD中的领域对象、值对象、聚合根

    一.DDD中的领域对象.值对象.聚合根 参考地址: DDD-快速理解聚合根.实体.值对象的区别和联系_王瑞学习笔记-CSDN博客聚合根.实体.值对象的关系:1.实体具有ID,生命周期,状态用值对象描述 ...

  5. DDD中聚合、聚合根的含义以及作用

    一. 聚合与聚合根的含义 1. 聚合 聚合往往是一些实体为了某项业务而聚类在一起形成的集合 ,举个例子,社会是由一个个的个体组成的,象征着我们每一个人.随着社会的发展,慢慢出现了社团.机构.部门等组织 ...

  6. java ddd聚合,DDD(五)--集合、聚合根

    1.引言 聚合,字面意思就很简洁明了,是把领域对象聚合在一起,并维护领域对象之间的关系. 聚合其实就是一个在不改变原有实体的情况下将若干实体聚集起来. 2.为什么要聚合呢 在开发中很多实体有着多个一对 ...

  7. DDD—快速理解聚合根、实体、值对象的区别和联系

    聚合根.实体.值对象的关系: 1.实体具有ID,生命周期,状态用值对象描述状态,实体通过ID进行区分是这个实体还是那个实体: 2.聚合根是实体,聚合根的ID全局唯一,聚合根下面的实体的ID在聚合根内唯 ...

  8. DDD 聚合根 限界上下文

    案例 微信账号:手机号 用户A注销微信账号,需要钱包数据.银行卡数据.亲属卡信息,同时被删除 对一个对象修改,会涉及大量关联对象状态的修改. 需要使所有关联对象的状态保持一致 Aggregate 聚合 ...

  9. java ddd聚合_DDD聚合根/存储库结构

    我认为AccountType是从Person聚合根引用的另一个聚合根. 有许多简单的聚合根是绝对正常的,见 Vaughn Vernon articles,见 part 1,p. 5: On one p ...

最新文章

  1. (0001) iOS 开发之收集第三方资源篇
  2. linux整理笔记之六:samba软件包使用
  3. stm32之iap实现应用(基于串口,上位机,详细源码)
  4. oracle排序非英文最后,Oracle中中文、数字,英文混杂形式的字段进行排序的方法...
  5. python定义类object_Python之ClassObject用法详解
  6. main run方法没用_多线程:解决Runnable接口无start()方法的问题
  7. Bailian2911 受限完全平方数【暴力】
  8. toad库进行分箱操作
  9. mysql的pdb文件在哪里_pdb是什么文件?pdb数据库文件怎么打开?
  10. [4G/5G/6G专题基础-157]: 无线数据承载DRB与无线信令承载SRB
  11. 未来IT行业前景如何?
  12. 电容式位移传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  13. append()与prepend()的区别
  14. sku设计mysql_如何设计SKU表结构
  15. 8除以2表示什么意思_8除以2等于4表示什么
  16. Oracle基础-ALC权限
  17. 网络协议基础09--HTTP
  18. python极坐标和直角坐标的转换
  19. unix时间戳和毫秒时间戳
  20. 捷的軟體開發流程(CMMI)

热门文章

  1. CF802L Send the Fool Further! (hard) 题解
  2. mybatis传入字符串分割成数组并遍历
  3. java inputstream write_将Java InputStream的内容写入OutputStream的简便方法
  4. 02.我有社保,为什么还要买保险?
  5. 关于做好“三证合一”有关工作衔接的通知
  6. SPARK官方实例:两种方法实现随机森林模型(ML/MLlib)
  7. (wetest服务器性能),独家开放服务器压测能力,WeTest“压测大师“上线解决产品服务器性能难关...
  8. 双翌视觉系统配合机械手大视野定位案例(单目标带角度抓取)
  9. 测试/开发程序员的修炼之路,这是一场持久战......
  10. cartographer_learn_5