识别实体与值对象的特征
甄别实体与值对象非常重要,正确与否会直接影响聚合的设计。
聚合是边界
在DDD中,聚合是实体与值对象的边界。一个聚合对外代表了一个完整的领域概念,遵循面向对象设计的基本原则,聚合内部往往由多个细小的高内聚领域概念组成。聚合内部的领域模型形成了一棵树,树的根必须是实体,可以称之为是聚合根(Aggregate Root),当然,也可以称之为根实体(Root Entity识别),它是聚合的唯一入口或出口。例如订单聚合定义了Order根实体,它就是订单聚合的唯一代言人。
在一个限界上下文的所有领域模型(实体和值对象)中,按照关系的强弱与概念的完整性,将其划分为多个聚合,就好像草原部落由一个个蒙古包构成了松散的聚居社群一般。
考虑到值对象与实体的差异,倘若需要管理它们的生命周期,则值对象不可能脱离聚合的边界单独存在。这就意味着,当我们要识别领域实体模型的聚合时,实体与值对象之间的强弱关系并不会影响到对聚合边界的界定。只要实体与值对象之间存在关系,无论关系强弱,该值对象都必须与存在关系的实体放在同一个聚合。如果一个值对象与多个实体之间存在关系,要么说明多个实体都属于一个聚合;要么意味着该值对象需要复制为多份,放到不同的聚合中,如下图所示:
如此一来,对于聚合边界的识别,就变成了对实体关系强弱的判断。只要我们正确地与值甄别了实体与值对象,在识别聚合时,就可以不再考虑值对象,如此就能降低识别的难度。
上下文的影响
虽然我们知道实体与值对象之间的本质差异在于是否具备唯一的身份标识(identity),然而许多时候,这一差异仍然显得似是而非。更何况,实体与值对象的定义并非绝对,在不同的上下文,同一个领域概念也可能定义为不同的设计类型。例如下图所示的钞票一枚:
在购买上下文,买卖双方只对象关注钞票的面值与货币类型,只要值相等,即可认为是同一个对象,因而需定义为值对象;在印钞上下文,每张钞票都具有一个唯一的标识,即使同为100元的人民币,只要ID不同,也会认为是不同的对象,故而定义为实体。因此,要正确地甄别实体与值对象,需要结合具体的上下文。
识别的特征
即便如此,仍然缺乏相对客观的判断标准。为此,我总结了如下几个特征。
相等性
甄别实体与值对象,可以首先从相等的特性进行判断。只要一个领域模型对象的属性值相等,就认为是同一个对象,应优先考虑建模为值对象;否则,需要为领域模型对象定义唯一标识,并建模为实体。
注意:在进行相等性判断时,不能将作为唯一标识的ID视为领域模型的属性。
例如地址领域概念,只要其属性值国家、省份、城市、街道与邮政编码相等,就可以认为是同一个地址,应将Address类定义为值对象。对于大家耳熟能详的订单领识别域概念,显然需要为其分配一个唯一的订单编号,因为理论上可能存在除订单编号外其他属性都相同的两个不同订单,应将Order定义为实体。
然而,在对相等性进行判断时,可能出现ID与属性存在一种隐含的对应关系。例如,出版行业中作为正规出版物的图书,具有唯一的ISBN号,它相当于是图书领域概念的ID,所以Book应定义为实体。可在对Book相等性进行判断时,也可以不通过ISB实体N进行相等性判断,基本上,只要书名、作者(译者)、出版社、价格、出版日期、版次、页数、字数等属性值相同,也可以认为是同一本书,那是否意味着可以将Book定义为值对象呢?
显然,在进行相等性判断时,考虑的属性越多,就会出现多个组合的属性形成一种“隐藏”的唯一标识特征,有一些体现业务规则的ID,自身就是根据属性值来定义的。例如,航班的唯一标识就可以根据承运公司二字码、航与值班号、起降机场三字码与执飞日期来决定。通过唯一标识固然可以决定是否同一个航班,根据映射的多个属性值,也可以判断相等性。这会让人在甄别实体与值对象时,显得摇摆不定。例如,腾讯会议的会议号是Meeting的身份标识,在比较会议的相等性时,倘若我们考虑了除会议号之外的其他属性,如会议名称、会议类型、开始时间、结束时间、创建人、创建时间等属性,不一样可以确定会议的相等性吗对象?
因此,除了判断相等性,还需考虑不变性。
不变性
Eric Evans建议将值对象定义为不变的类,实则是因为根据值判等的值对象就应该具有不变性。仍以购买上下文的钞票为例,50元+50元=100元,这100元与原来的50元是另一张不同的钞票:
反之,一个对象除了ID,其余属性值都可以修改,不需要创建一个新的对象,就可以认为该领域对象是可变的,应考虑定义为实体。如前所述的特的Meeting对象,只要meetingId值不变,如会议名称、会议类型、开始时间、结束时间这样的属性值即使发生了天翻地覆的变化,我们也认为它是同一个会议。显然,应将Meeting定义为实体。
再考虑一个典型的订单聚合:
为什么我们要将订单聚合中的OrderItem定义为实体?如果不考虑ID属性,只要orderId、product与quantity值相同,完全可以认为是同识别一个订单项。然则,订单项的quantity值是可以更改的,更改了数量的订单项也不会认为是不同的订单项。订单项的可变性决定了它应该定义为实体。
为何要将OrderItem的Product属性定义为值对象呢?要知道,该Product类型还定义了productId属性,既然具有身份标识,不应该定义为实体吗?因为在订单上下文中,商品的productId来自于商品上下文的商实体品ID,在订单聚合中,可以将productId视为Product类的属性值。只要productId、name和price值相同,就可以认为是同一个商品,且它们的值是不变的。这正是将Product定义为值对象的原因所在。
独立性
即使考虑了相等性和不变性,仍有一种例外情形,那就是考虑独立性特征。值对象作为实体的属性必定附属于实体,不能单独存在;如果一个领域对象既满足了相与值等性,又满足了不变性,可定义为值对象;可是,如果它单独存在,且需要管理其生命周期,就需要将这样的类“升级”为实体。
考虑考勤上下文的假期领域概念。由于中国农历假期的缘故,每年都需要配置新的假期。假期概念对应的Holiday类定义为:
显然,该类的所有属性值相等,即可认为是同一个假期,一旦修改了假期的值,也可以认为是不同的假期,即Holiday类同时满足相等性和不变性,应对象定义为值对象。可是,在考勤上下文的领域模型中,Holiday类是完全独立的,不依附于其他任何实体,而它也需要管理生命周期。这时,就应遵循独立性特征,将其“升级”为实体。
优先级
以上三个特征并无重要性排列,需综合考虑。如果仍然无法判断,就遵循优先级原则:优先将领域概念建模为值对象。
- ·标签: 云知声U2 LLMStatsScore LongBench-V2 ClaudeOpus
- ·5个用于培养数字工作场所的优秀大数据工具
- ·标签: Google Play Alphabet 应用内购买 订阅服务费
- ·标签: 信也科技 FINV 金融科技 财报
- ·标签: 铠侠 NAND闪存 QLC SSD BiCS10
- ·开发者如何在 iOS 26 中使用 Apple 的本地 AI 模型
- ·云安全日报210629:红帽OpenShift云应用平台发现执行任意代码漏洞,需要尽快升级
- ·标签: Ai
- ·lol上票是什么梗
- ·阿里第四财季实现营收2082亿元 同比增长2%
- ·腾讯云联合英特尔、美团等发布SuperEdge边缘容器开源项目
- ·云计算核心技术Docker教程:Docker Swarm 模式管理集群列出节点
- ·图灵奖获得者约翰・轩尼诗:数据和机器学习让世界变得更美好
- ·标签: 灵心巧手 Linker Hand 具身智能 灵巧手
- ·一文梳理视觉Transformer架构进展:与CNN相比,ViT赢在哪儿?
- ·网宿科技胡世轩:数据中心亟需“液冷”加持
- ·标签: 思派健康科技 企业保险服务 医生研究协助 商业保险经纪
- ·亚马逊与苹果抛弃英特尔芯片 机算行业话语权或将转移
- ·标签: 中国石油 中油电能 塔里木上库 国网新源
- ·云计算核心技术Docker教程:Docker Swarm 模式使用 Docker Configs 存储配置数据
- ·如果让AI根据文字画「抽象画」,那得成什么样?|DeepMind新算法
- ·欧盟接到成员国投诉 或对Facebook收购Kustomer展开调查
- ·Facebook第二季度营收291亿美元:净利同比增长101%
- ·标签: 山金国际 黄金生产商 中信证券 港股IPO
- ·Opera 推出 AI 驱动的 Neon 浏览器,开启智能上网新体验
- ·京东云发布混合云操作系统云舰 向产业发出三重承诺
- ·https://www.qidulp.com/search?query=歌外推【tg:seogoogle987】,lHP
- ·https://www.tcv.org.uk/search/歌外推【tg:seogoogle987】,HKR
- ·https://www.oprny.com/search.php?search_query=歌外推【tg:seogoogle987】,3W0
- ·https://www.dba.dk/soeg/?soeg=歌外推【tg:seogoogle987】pQ2
- ·https://www.symatoys.com/search.html?ID=UyMD6aO58bPrJvQAB1I0N69KzJBZeNPC&keyword=歌外推【tg:seogoogle987】,acL
- ·https://www.remit.co.jp/pt/?action=CHECK&s=歌外推【tg:seogoogle987】,3ha
- ·https://www.flickr.com/photos/tags/歌外推【tg:seogoogle987】lYP
- ·https://www.tiktok.com/tag/歌外推【tg:seogoogle987】,yHC
- ·https://www.mygrandma.com/Items.aspx?search=歌外推【tg:seogoogle987】,Jx8
- ·https://www.skicheck.at/en/?action=CHECK&s=歌外推【tg:seogoogle987】,VAt
- ·标签: BOSS直聘 赵鹏 NaNbeige4.1-3B 蓝领招聘
- ·这只日本AI爆火:草图实时变身二次元老婆,还有512种参数可调
- ·1 分钟快速使用 Docker 上手新版 Sentry-CLI - 创建一个版本
- ·美国军方高层开始依赖 ChatGPT 辅助决策,引发关注
- ·谷歌员工年薪曝光:硬件工程师26万美元、软件工程师30万
- ·标签: 软银 英伟达 孙正义 AI泡沫
- ·标签: 浙江智屏 阿里巴巴 小米 海信
- ·Twitter将允许研究人员获取公共数据
- ·云安全日报220623:红帽数据库管理系统发现执行任意代码漏洞,需要尽快升级
- ·苹果股东大会定档 改为线上举办!CEO库克年薪曝光
