我从DDD开始并试图申请我当前的项目,但你可以假设我有数千个问题。
在这里,我提供了一个示例域名,以便我可以提出不同的问题并作为练习,您可以向我解释如何制作内容。
我们的假设系统必须控制公司以及每个公司的工作人员。
一个人只能在公司工作,公司可以有很多员工在工作。
系统必须允许向公司添加新员工。为此,它会收到公司id
和新员工的name, surname, age
。有一些限制要满足:
name, surname and age
。我心里一团糟:)
实现我正在考虑的操作:
CompanyRepository->findCompanyById
以检索公司实例。company->addEmployee
将员工附加到公司。company->AddEmployee
检查中,新员工满足条件(规格)。CompanyRepository->save(company)
除了员工外,还要保留公司。因为company+employee
作为集群(聚合)进行管理,所以我认为公司是集合根。
company+employee
是一个聚合,就像我描述的保存集群company+employe
一样,当我从存储库中检索公司实例时,我是否也必须检索所有相关的员工?CustomerRepository->findEmployeeByName(idCompany, nameEmployee)
或更好地创建特定的EmployeeRepository
。答案 0 :(得分:3)
什么是好或坏只是一种意见。 DDD不应该是一个教条,你可以充分利用它和你自己的补充来构建良好的软件架构。
不,公司可以懒惰地加载员工(即,在检索到公司后第一次运行时访问Employee
属性)或公司可以实现Load
方法,该方法也支持分页只加载所需的员工。
您应该在存储库级别(例如ICompanyRepository.ContainsEmployee(Employee)
)实现此功能,并使用底层数据映射器执行此繁重的操作。
此外,我倾向于将规范称为存储库中的前/后条件,因为它是确保在所有情况下都能满足它们的唯一方法。
我会避免它,但如果你想确保很多域规则,你需要在规范中使用它们。顺便说一句,我不会使用存储库,但我会改用服务。
正确的地方取决于要求。如果要执行检查以确保域对象以有效状态存储在存储库中,如果要从ICompanyRepository.Add
或ICompanyRepository.Update
或{中调用规范,我发现没有问题{1}}。这里的要点是,当它们存储在存储库中以及何时被检索时,您不应该验证对象状态。如果您的规范和代码是可靠的,如果存储库已经过滤了域对象并且已将它们存储在基础数据存储中,那么您可以确定读取操作将获得有效的域对象。
旁注:虽然你不应该根据底层数据存储(关系,NoSQL,文件系统......)对域进行建模,但是你不应该这样做像教条一样应用DDD。如果底层数据存储提供了更好的方法来定义数据约束,我会尝试使用它们而不是实现可能需要访问数据的复杂规范。
您的解决方案应该是最佳软件架构和运行时性能之间的平衡。