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