gre*_*fox 5 design-patterns domain-driven-design ddd-repositories
构建时间跟踪应用程序我正在尝试确定设计聚合根的最佳方法.
基本核心实体是Client,Project,Employee,ProjectAssignment,Department,Timesheet.客户有一个或多个项目,项目有一个或多个员工(通过ProjectAssignment),一个员工属于一个部门,时间表链接项目,员工.
客户端似乎是一个明显的聚合根.
Client -> Project -> ProjectAssignment -> Employee
Run Code Online (Sandbox Code Playgroud)
关于其他总量,我有点不确定最好的方法是什么......
我刚在想...
Department -> Employee -> Person
Run Code Online (Sandbox Code Playgroud)
或者将员工和部门完全作为单独的聚合.员工只能在一个部门和一个部门.但是,部门是自引用以创建部门层次结构.
您如何处理聚合根之间共享的实体?
小智 10
DDD不是关于数据结构,也不是关于这些结构之间的关系,而是关于这些数据发生的变化以及这些变化的边界.DDD在许多地方都很难解释,包括多个视觉课程或会议,人们构建一个简单的应用程序,专注于单个用户,并努力尽可能多地强加DDD原则.
领域驱动设计的核心原则是边界.当您尝试查找聚合时,首先要考虑您在应用程序中执行的进程以及您需要具备的进程,以使这些进程保持一致.然后构建执行此更改的单个实体,并将其与聚合中的任何其他所需实体(值对象)一起包装.然后将一个实体作为所有使用这些实体执行的进程的网守.
从数据结构开始设计是人们在DDD失败的首要原因.从您提供的内容到我,似乎您的聚合更像是一个ProjectAssignment
,也许是一个Timesheet
,因为这可能会奠定核心业务逻辑.所有其他的东西几乎都不是值对象(或者如果你必须使用orm的实体),可以使用简单的crud样式方法创建.关于实体和价值对象之间的差异有很多讨论和博客文章.人们倾向于给他们在域中的"对象"赋予一些意义,但对于领域专家来说,我们花费大量时间创建的那些珍贵对象只是价值,仅此而已.所以不要推广Client
或Department
作为聚合根 - 它们只是价值观.
不要害怕你使用crud.您在设计域时遇到的许多事情都只是域导出的价值对象.他们只是使用它们来对真实的业务实体进行操作.他们不关心如何Client
创建a,如何Department
创建a或如何Department
创建层次结构.他们只是创建它们然后编辑或删除它们.因此,用于描述a Client
或a 的单词Department
将只是创建,更新或删除 - 而这些单词对于无所不在的语言(域语言)来说是非常差的候选者.无处不在的语言在DDD中是如此被低估的模式.如果你正确使用它,它将为你节省时间,你花在设计的东西,这对业务无关紧要.每次你认为你需要创造一些东西或更新一些东西 - 使用crud!不要用DDD原则打扰你自己,因为它们很简单,不适用于创建或更新等词.
请记住,只有在您可以访问域专家时,DDD才会在协作域中闪耀.同时拥有业务专家和开发人员帽子真的很难.至少将设计分组或至少成对,尝试一些事件风暴.根据我的经验,单独创建一个像样的ddd设计几乎总是会失败.
在设计聚合时,您应该考虑有界上下文和不变量。据我了解,您只讨论了一种有界上下文。关于您指定的不变量,即一名员工只能在一个部门工作。据我所知,聚合根(AR)是:Client
、和。Project
Employee
Department
ProjectAssignment
应该是 AR 中的一个值对象Project
,它包含就业 ID 和其他数据(如分配日期)的列表。
Timesheet
可以是包含开始日期和结束日期等其他数据Employee
列表的值对象。Projects IDs
Employee
AR 可以引用它Department ID
强制执行的不变量,即一名员工只属于一个部门。
归档时间: |
|
查看次数: |
1247 次 |
最近记录: |