Design patterns 产品配置关系

Design patterns 产品配置关系,design-patterns,domain-driven-design,Design Patterns,Domain Driven Design,我正在创建签出流程,其中一个步骤涉及配置产品。用例如下所示: 产品配置 产品配置是一组可配置的选项组 选项组 每个选项组可以由一个选定的选项(或无)组成,该组由多个选项组成 用户可以在产品组中添加和删除选项 例如,选项组可以称为数据库 选项 选项是选项组的特定选项 例如,对于属于数据库选项组的选项,特定选项可以是MySQL或MS-SQL 选项组相关性 选项组可以依赖于另一个选项组,因此,如果无法满足目标选项组的要求,则会过滤掉特定项 只有一个目标依赖项,我们不需要担心产品选项组中指向多个目标产品

我正在创建签出流程,其中一个步骤涉及配置产品。用例如下所示:

产品配置

产品配置是一组可配置的选项组

选项组

每个选项组可以由一个选定的选项(或无)组成,该组由多个选项组成

用户可以在产品组中添加和删除选项

例如,选项组可以称为数据库

选项

选项是选项组的特定选项

例如,对于属于数据库选项组的选项,特定选项可以是MySQL或MS-SQL

选项组相关性 选项组可以依赖于另一个选项组,因此,如果无法满足目标选项组的要求,则会过滤掉特定项

只有一个目标依赖项,我们不需要担心产品选项组中指向多个目标产品选项组的选项

例如,为了允许在数据库产品组中选择MS-SQL选项,必须从操作系统选项组中选择Windows选项

类似地,为了允许在数据库产品组上选择MySQL选项,必须从操作系统选项组中选择Windows或Linux选项

结构

在上图中,MySQL(ID=201)产品选项依赖于OS产品选项组的Windows(ID=101)或Linux(ID=102)产品选项。如果选择了这些操作系统选项中的任何一个,则会显示MySQL

MS-SQL(ID=202)产品选项依赖于OS产品选项组的Windows(ID=101)产品选项。仅当选择Windows操作系统时,才会显示MS-SQL

问题-在哪里存储依赖关系映射数据?

随着代码的发展,现在的问题是在哪里存储产品选项及其组之间的关系依赖关系映射。我所质疑的主要问题是:

分开汇总,管理交易

我们是否将映射存储在其自身的聚合中,如果是,我们将如何检测并停止删除引用的产品和ProductOptionGroup

例如,如果存在对操作系统窗口的依赖,我们必须对其进行保护,如果其他OptionGroup对其有依赖,则不允许从OS ProductOptionGroup中删除

这是否由应用程序服务完成?如何在我们的代码中构建事务

内部聚合、更轻松的事务管理、更高的并发问题可能性

我们是否将映射存储在OptionGroup聚合中,但是如果我们这样做,如果有人更新了OptionGroup的名称和描述,而另一个用户正在编辑映射数据,则提交时会出现并发异常

这并没有真正意义,因为如果有人更新名称,映射数据不应该失败,因为它们是两个不相关的概念

在这种情况下,其他人会怎么做?我如何最好地为上述场景构建代码?或者我错过了从我的集合中看到的更深层次的洞见,如果重新设计,事情会变得更容易

我认为DDD设计禁止从外部访问ProductOptionGroup内部的ProductOptions,但目前我无法考虑如何以其他方式对其建模

编辑Giacomo Tesio的建议答案

感谢您提出的答案,感谢您花时间提供帮助。我真的很喜欢整洁简洁的编码风格。您的回答确实提出了一些进一步的问题,如下所示,我很可能是找错了方向,但请澄清:

  • OptionGroup
    中,有一个
    \u descriptions
    字典,用于包含选项的描述。

    为什么选项描述属性不是选项对象的一部分

  • 您提到的
    选项
    是一个值对象。

    在这种情况下,它有一个名为
    \u id
    的成员,类型为
    OptionIdentity
    ,是否允许值对象具有标识id

  • 选项的代码中,它采用
    id的构造函数和
    依赖项列表

    我理解
    选项
    仅作为
    选项组
    的一部分存在(因为
    选项身份
    类型需要
    选项组身份
    类型的成员。一个
    选项
    是否允许保存对另一个
    选项
    的引用,该选项可能位于另一个
    选项组
    聚合实例中?这是否违反了DDD规则,即只保存对聚合根的引用而不引用其中的内容

  • 通常,我将聚合根及其子实体作为整个对象进行持久化,而不是单独进行持久化,为此,我将对象/列表/字典作为聚合根中的成员。对于
    选项
    代码,它需要一组依赖项(类型为
    OptionIdentity[]
    )。

    如何从存储库中重新水化
    选项
    ?如果它是包含在另一个实体中的实体,那么它是否应该作为聚合根的一部分来传递给
    OptionGroup
    的构造函数


  • 这是一个精心设计的问题,即使领域模型应该使用专家们谈论的领域的语言,我猜领域专家们不会谈论产品配置、产品选项组和选项。因此,你应该找一位d方面的专家谈谈