• DDD中的聚合和UML中的聚合以及组合的关系


    UML:
    聚合关系:成员对象是整体的一部分,但是成员对象可以脱离整体对象独立存在。
    如汽车(Car)与引擎(Engine)、轮胎(Wheel)、车灯(Light)之间的关系为聚合关系,引擎、轮胎、车灯可以脱离车而存在,比如把一个引擎换到另一个汽车上也可以。

    组合关系:也表示的是一种整体和部分的关系,但是在组合关系中整体对象可以控制成员对象的生命周期,一旦整体对象不存在,成员对象也不存在,整体对象和成员对象之间具有同生共死的关系。

    所以,聚合和组合的差别就一点:整体和部分的生命周期是否一致,即整体消亡后,成员对象是否可以脱离整体对象而单独存在。

    DDD聚合关系:
    也是一种整体和部分的关系,部分脱离整体会变得毫无意义,强调同生共死的一致的生命周期。所以,从定义来看DDD中的聚合应该和UML中的组合关系是一致的。

    按照上面的定义,我们在来分析一下一个典型的例子,就是公司和部门的关系。

    UML的角度:
    1、一个公司由多个部门组成,所以满足整体和部分的关系;
    2、一个部门不能脱离公司和加入到其他公司;

    所以,在UML中应该属于组合关系,没有问题。

    DDD的角度:
    虽然基于UML的角度,公司和部门属于组合关系,那在DDD中是否应该把部门聚合在公司下面呢?我的看法是,虽然从生命周期上,确实部门不能脱离公司。
    但是DDD的聚合设计要考虑的因素会更加丰满,比如:

    • DDD强调需求和Bounded Context,也就是会基于需求和上下文进行建模,我们建模前必须要先确定当前的需求和上下文是什么;
    • 整体在当前上下文是否强关心部分的存在;
    • 整体和部分之间是否存在某些不变性规则;
    • 操作整体与操作部分的业务场景是否一致;
    • 性能问题,如果整体聚合的部分数量过大,那也不会考虑聚合,即小聚合原则;
    • 一致性问题,我们在设计系统时,即便把本该是聚合在一起的对象分开设计为多个聚合,也可以从技术上去解决一致性,比如通过领域服务来完成多个聚合的协同创建、删除、修改,并能通过数据库事务来保证严格的强一致性;
    • DDD领域建模会对领域概念进行抽象,所以再领域模型中,也许就没有公司了,而是只有部门,把公司也看成是一个顶层的部门就行,所以自然就不会有公司这个聚合根了;

    所以,在进行DDD聚合设计时,如果仅从整体删除后部分会变得毫无意义(即对象之间的生命周期)这个点去推导的话,那考虑的就太单薄了,很有可能会得出不合理的聚合设计。
    这是没有认真分析业务需求,没有分析业务规则不变性,没有对领域概念进行合理抽象,没有进行OO软件设计原则的应用的表现。

    我想,这也是为什么DDD聚合设计为何会如此之难的原因了。

    所以,结论是,以上案例由于需求不明,无法进行聚合设计,大家是不是很意外呢?居然没有给出答案:)

  • 相关阅读:
    vue--父组件向子组件传参--父组件定义v-bind:参数名--子组件接收props----子组件调用父组件的方法(子组件向父组件传参)父组件@事件名称--子组件接收this.$emit
    vue--组件切换--带动画效果---component
    js string类型转换成数组对象类型---eval
    Vue--创建组件-template---定义私有组件
    vue--自定义标签属性--用于多个事件共同引用一个组件--但是两个事件要实现的功能不同-避免冲突
    vue--组件动画效果--淡入淡出--位移
    vue---向后台添加数据--删除数据--事件方法传参---在单页面配置url请求地址--暂时没有用到webpack
    vscode安装Bootstrap插件--方便补全代码段
    vue-resource--ajax请求数据
    生命周期演示--从加载--渲染--销毁
  • 原文地址:https://www.cnblogs.com/yanglang/p/11081486.html
Copyright © 2020-2023  润新知