You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DDD实践疑问:产品分类应设为值对象还是实体?

产品目录上下文里Product Category的DDD定位与持久化方案

首先明确DDD里实体和值对象的核心判断依据:

  • 实体:拥有唯一标识,具备独立生命周期,标识不变则实体身份不变,属性可变更。
  • 值对象:无唯一标识,属性完全相等则视为同一对象,通常设计为不可变(属性变更等价于生成新的值对象)。

针对你的场景,分两种业务情况来定:

场景1:分类是独立维护的业务实体(需同步变更到关联产品)

如果你的业务要求:

  • 运营可以独立对分类做CRUD(比如新增分类、修改分类名称、禁用分类)
  • 分类变更后,已关联该分类的产品要同步显示最新的分类信息(比如分类改名后,所有该分类下的产品都显示新名称)

这种情况下,Category是实体,且建议作为独立聚合根:

  • 它有自己的唯一标识(如category_id),具备独立的生命周期(从创建到禁用/删除)
  • 产品(Product聚合根)仅通过分类的ID来关联,而不是直接持有分类对象(避免跨聚合耦合)

对应持久化方式:

  • 数据库层面:
    • 新建category表,存储分类的标识(id)、名称(name)、状态(status)、层级(如parent_id)等字段
    • product表中存储category_id作为外键,关联category表
  • 领域层:
    • Product聚合根持有CategoryId值对象(封装分类ID),而非Category实体
    • 当需要展示产品分类信息时,通过CategoryRepository查询对应的Category聚合根

场景2:分类是产品的描述性属性(无需同步变更)

如果你的业务规则是:

  • 分类列表仅作为产品创建/编辑时的选择项,分类的后续修改不影响已关联的产品(比如选了“电子产品”后,分类改名成“数码产品”,老产品仍显示“电子产品”)

这种情况下,Category是值对象:

  • 它没有独立的生命周期,仅作为产品的一部分属性存在
  • 产品中的Category值对象是创建时从分类列表中复制的属性快照,后续分类列表的变化与已存在的产品无关

对应持久化方式:

  • 数据库层面:
    • 方案1:直接在product表中存储分类的核心属性(如category_code、category_name),无需关联分类表
    • 方案2:若需统一维护分类选择列表,可建category_dict表,但product表存储的是选中时的属性副本(而非外键),确保产品数据不受分类表修改影响
  • 领域层:
    • 设计Category值对象,包含code、name等属性,且设为不可变(如需修改产品分类,需替换为新的Category值对象)

关键决策点

核心判断标准是分类的变更是否需要同步到已关联的产品:

  • 若需要同步 → 实体(独立聚合根)
  • 若不需要同步 → 值对象

内容的提问来源于stack exchange,提问作者Jester1811

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 12:00:55