• 老毕
    2019-10-21
    陈述一下我的学习心得:实体和值对象的目的都是抽象聚合若干属性以简化设计和沟通,有了这一层抽象,我们在使用人员实体时,不会产生歧义,在引用地址值对象时,不用列举其全部属性,在同一个限界上下文中,大幅降低误解、缩小偏差,两者的区别如下:
    ①两者都经过属性聚类形成,实体有唯一性,值对象没有。在本文案例的限界上下文中,人员有唯一性,一旦某个人员被系统纳入管理,它就被赋予了在事件、流程和操作中被唯一识别的能力,而值对象没有也不必具备唯一性。
    ②实体着重唯一性和延续性,不在意属性的变化,属性全变了,它还是原来那个它;值对象着重描述性,对属性的变化很敏感,属性变了,它就不是那个它了。
    ③战略上的思考框架稳定不变,战术上的模型设计却灵活多变,实体和值对象也有可能随着系统业务关注点的不同而更换位置。比如,如果换一个特殊的限界上下文,这个上下文更关注地址,而不那么关注与这个地址产生联系的人员,那么就应该把地址设计成实体,而把人员设计成值对象。
    展开

    作者回复: 你太有才了。理解的很透彻。

     6
     86
  • stg609
    2019-10-29
    我对于实体的看法和老师基本一致,但是值对象有补充,愿讨教。

    首先,值对象没有id的概念,由其所拥有的所有属性来识别,属性值是不可变的。换句话说就是只要两个对象的所有属性都一样那就认为是同一个对象,可以互相替换, 但改变任何一个属性,就是两个不同的对象。

    举个例子,你手里有一张毛爷爷,你不会在意这张毛爷爷是不是之前的那张,你在意的只是它的价值。

    但是一个东西是被建模成值对象还是实体,不是一成不变的。
    举个例子,汽车是一个实体,那车上的引擎可以认为是值对象,对于汽车而言,引擎坏了,换一个一样的就好了。但是对于引擎厂商来说,引擎就是个实体,厂商需要跟踪每个引擎的一些数据变化,不可能这个引擎丢了,随便拿一个新的引擎就可以替代的。

    值对象的好处
    既然是DDD, 从基础设施层,如数据库角度去考虑它的好处感觉有些牵强。我认为还是从如何降低业务复杂性角度出发会更合适。

    ·很容易判断两个对象是否相等
    ·不可变也确保了值对象永远都是正确的,尤其是在并发环境中不会被意外修改,是线程安全的。比如调用 String.ToUpper 会创建一个新的字符串而非修改原来的字符串,这可以避免其他使用了同一字符串的代码出现错误。
    ·值对象既然是不可变的,这使得它天然适合被重用,可以提高性能,就好像很多编程语言中的 String 是不可变的,同样的字符串只占用一份空间。

    所以,鉴于值对象比实体更轻量级,高性能且线程安全,一般建议总是优先建模值对象,而非实体。

    另外,值对象本身虽然是没有id的,但是并不妨碍它的属性是一个实体。
    展开

    作者回复: 专业,非常同意你的观点。

     2
     15
  • huaweichen
    2019-10-21
    请问老师,本课程的后面章节,会有关于如何落实DDD的开发实战案例吗?

    作者回复: 会有的,包括事件风暴、从中台的领域建模、到微服务设计都会有案例的,最后会有一个典型案例把这些知识串起来。不过这些案例主要是设计为主,会设计出不同分层的类、服务等,不到具体的代码实现。

    
     5
  • FIGNT
    2019-10-21
    实体和值对象都是领域模型的成员,实体是业务唯一性的载体,是个富对象,包含业务逻辑和唯一标识。值对象是属性的集合,没有唯一标识,只是数据的容器,没有业务逻辑。值对象是实体的一部分,为了简化设计,将部分相关属性抽离成值对象。如果值对象变动,原来的值对象可以直接丢弃。也可以理解为值对象是当时数据的快照,只是当时的状态。值对象过多会导致业务的缺失,影响查询性能。具体哪些属性可以作为值对象存在要具体问题具体分析。

    作者回复: 理解很透彻。

    
     4
  • Alvin
    2019-12-10
    用项目结构来通俗的讲,实体就是我们平时项目中entity包中的类,与数据库表直接映射,值对象文章开头处一直误以为是view层的VO对象,后面才了解它其实就是实体中的属性对象。不知我这么粗浅的领悟对不对

    作者回复: 没错,理解正确。
    但是实体在不同的层有不同的形态,如PO,DO,DTO等。实体不一定与数据库表一一对应。

    
     2
  • 密码123456
    2019-10-22
    实体和值对象,就是把业务拆分,拆分再拆分。直到能够通过“对象”表达某一时刻的业务。实体就是业务中,不可再分割的对象。值对象是对实体的补充。举例:比如网购。商品最重要。商品就是实体,商品的状态比如下单,物流中。只是商品的状态,没那么重要的就是值对象。看到后面才发现,值对象和实体的定义是那么的难!

    作者回复: 抓住几个关键点就不那么难了。比如:实体可修改,值对象不可修改,只可以整体替换。实体是实实在在的业务对象,值对象只是对对象的描述。值对象依附以实体,实体没了值对象也就没了。

    
     2
  • 。
    2019-10-22
    学到了和以前设计不一样的地方。DDD弱化了数据库设计,减少了表之间的关联关系,将不用来查询的静态值设计为值对象,作为一个字段存储到实体对应的表中。减少了数据库设计的复杂度,避免了复杂的关联。
    教数据库的老师估计想打人了😂

    作者回复: 哈哈,出发点不一样,所以观点会有差异。

    
     2
  • james.d
    2019-12-19

       在实践中我发现值对象是最容易被误解和忽视的DO,缺乏值对象的建模往往导致模型的不完整,最终系统有缺陷。值对象与实体具有相同的领域规则,是聚合中的重要组成部分,而且也是要参与业务构建的。
       值对象在领域内不具备生命周期,领域也不会修改值对象的属性,所以一个值对象在领域内具有不可变性。在该领域中业务不关心该对象的历史和将来,只关心值对象当前的属性对业务的影响。即便值对象的属性包含Id,领域也不会根据该Id去跟踪值对象的变化。
    一个领域内的实体在其他领域中可能建模为值对象更合理,值对象一个重要的使用场景是生成快照,用于还原业务现场。比如订单中的商品,地址等等。
    展开
    
     1
  • DullBird
    2019-10-30
    有个问题想问一下:
    一个组织管理的系统,一个人是部门的主管。
    这个业务中,人是人员实体,部门是组织实体,那么人是部门的主管,
    这个关系设计成实体还是值对象。
    我认为修改这个关系,实质上是替换了关系,我认为是作为值对象,
    但这个点一直没想太明白。
    展开

    作者回复: 按照你的描述,我理解是有人员和组织两个聚合。
    人员和组织信息各自维护。但组织实体中会有一个字段保存部门主管信息,对吧?
    在人员和组织聚合中,人员是实体,组织也是实体。
    组织实体的部门主管信息来源于人员聚合,对吧?
    这样的话,组织聚合中的组织实体的部门主管字段应该被设计为值对象。它可以被人员聚合中的其它人员整体替换。
    不知道理解的对不对?

     1
     1
  • 心浮天空
    2019-10-21
    值对象对实体而言的作用是什么?值对象的缺失是否会破坏实体的完整性?
    实体对象一般会对应着单独的功能对其信息维护, 而值对象没有单独的维护功能, 其生命周期与实体的生命周期一致?

    作者回复: 值对象是依附于实体的,是实体属性的一部分。它是实体的若干个属性的集合,为了概念完整性因此将具有一定业务含义的多个属性,组成一个属性集。
    实体的业务功能非常丰富,是业务对象的基本单元,值对象生命周期依赖于实体的,实体没有了,值对象也就没有了。

    
     1
  • 水如天
    2020-02-09
    老师好,请教下,如果我们需要记录每次值对象的修改记录,并且进行比较。比如,Address这个属性,修改了三次,比较三次地址是如何修改的,这时候adress如何设计呢?
    
    
  • 孤帆
    2020-02-06
    还有文中的 xx形态,这是自创的术语吗?
    前面文章还强调“通用语言”,这里自创这些”xx形态“的术语做什么?

    谁来确定你的这些术语是计算机工程师的通用语言?
    
    
  • 孤帆
    2020-02-06
    在代码模型中,实体的表现形式是实体类,这个类包含了实体的属性和方法,通过这些方法实现实体自身的业务逻辑。在 DDD 里,这些实体类通常采用充血模型,与这个实体相关的所有业务逻辑都在实体类的方法中实现,跨多个实体的领域逻辑则在领域服务中实现。

    举个例子,平时的 FooServiceImpl 没有了,直接使用 Foo 来实现。
    看起来有点搞笑,有点像PHP开发。
    
    
  • 发飙的蜗牛
    2020-02-05
    实体和值对象是DDD领域建模中最基础的领域对象,体现了领域业务模型设计。实体具有唯一标识,并且在整个系统业务生命周期中这个标识保持不变,是富对象,具有业务行为和业务逻辑。值对象依附于实体而存在,是若干属性的集合,用于描述实体的某些特征,没有唯一标识。抽离值对象主要是为了体现业务含义和概念完整性,能够简化数据库设计提高数据库性能。在DDD领域建模过程中,需要关注实体及其值对象之前的关系,一个聚合中的实体在另一个聚合中可能是值对象。
    
    
  • 莫离
    2020-01-31
    实体是领域中处理业务的最小单元,值对象是实体的属性,这样理解对吗?有个疑问是值对象可以是实体吗?就像传统数据库设计那样,还是说只能是嵌入式设计。还有就是比如说数据库存储的多个实体,但是为了某些业务搜索方便又在es做了多个实体聚合的文档,这样又相当于生成了一个新实体,对于这种设计又应该怎么来理解呢

    作者回复: 实体和值对象本质上都是属性的集合,是否设计为值对象要根据具体场景,如果这个属性集合的数据来源于其它的聚合,在本聚合只让整体修改,就可以设计为值对象。比如送货地址来源于客户中心,在订单中的送货地址只能整体从客户中心中获取并修改。那送货地址就是值对象。
    关于实体的理解,建议把他们放在不同的层去理解,领域层的实体是运行的概念,而存储的实体是持久化对象的概念,它们有关联,但并不一定是一对一的关系。多个领域实体可以跟一个持久化实体对象映射。所以在领域层和基础层之间会有DO和PO的转换。

    
    
  • Geek_d38f30
    2020-01-19
    对业务重要的就用实体,方便标记查询修改(通过唯一ID)。对业务不重要的就使用值对象,简单的存储数据。.值对象可以简化数据设计,但是有代价的。(前提你真的要确定这个对象真的不重要)

    作者回复: 谈不上谁重要谁不重要哈。他们属于领域模型的不同角色。

    
    
  • Iqexception
    2020-01-14
    读写的权衡,如果某些属性集合很少修改,但是经常查询,为了提高性能冗余一些字段也是可以接收的。
    值对象与实体的区别有点像Java中值和对象的关系,值是不可变的,对象以引用地址为id经常变化
    
    
  • 飞肥
    2020-01-13
    架构一般是演进式的。以上述人员和地址为例,假设前期业务场景不需要修改地址,一个人员也不需维护多个地址,那么把地址作为值对象就是合理的。数据模型可以将人员和地址放在同一表中维护。假设后续场景变化,一个人需要多个地址,且每个地址有可能变更。就需要把地址作为实体,表也需要变更。
    请问老师,如何通过实体和值对象,更优雅的应对这个变化呢?谢谢

    作者回复: 如果这个值对象不对外提供统计和复杂查询的话,可以将它设计为Json串的方式,这样就具有较高的灵活性。
    其实很多值对象很多时候体现了数据的冗余,它在其他聚合有对应的实体,可以新增和修改,这些数据会被其它聚合使用,但是在这些聚合不可修改,只能被实体整体引用。在领域建模的时候需要关注这类对象或值对象的设计。

    
    
  • Geek_68f3a7
    2020-01-09
    如果是记录状态的枚举类呢?他没有唯一标识不能做为实体,但是又不具备值对象的要求,因为他有可能会更改,这样的话应该如何设计?

    作者回复: 枚举类就是一个值对象。它一次只有一个值,而且是整体修改。

    
    
  • maomaostyle
    2020-01-09
    我理解值对象好比描述实体对metadata?但是在业务视角下谁做实体,谁做metadata可能各有各对看法?

    作者回复: 有点类似。

    
    
我们在线,来聊聊吧