domain-driven-design - 当它们是数据库规范化的一部分时如何处理域中的关系
问题描述
你有Job
*--1 ,所以在你的数据库中你的表中Board
会有一个。board_id
jobs
现在,在域中,Job
可以没有Board
. 因此,考虑向它添加boardId
属性对我来说并不合乎逻辑。
可以通过 管理它BoardRepository
吗?例如打电话给BoardRepository.addJob(Board board, Job job)
?所以存储库会将作业映射到数据库对象,然后board_id
在插入时添加字段?
问题是......如果我想通过查询作业/jobs/{id}
,我需要boardId
在域类中有属性,所以它不会映射到正确的 DTO。
希望我很清楚。
解决方案
通常每个存储库都有一个聚合。所以 Repository.addJob(Board board, Job job) 似乎不是一个好的选择。我不知道您的问题域..但是当我们将董事会作为一个集合或集合的根实体时,董事会负责管理其工作。所以它保留了一份工作列表,其中 Job 可能是另一个实体。一般来说,聚合是一个连接域对象的集群,它的作用就像一个门面,用于操纵它的状态以及它的实体和值对象的状态。通过应用这些原则,您可能会以这样的方式结束:
Board.addJob(Job job)
BoardRepository.add(Board board)
如果您的查询变得过于复杂并且不适合您的 DDD 模型,那么只需添加一个将简单 dto 映射到数据库的附加 QueryService 就可以在逻辑上分离写入和读取模型。希望我能提供一点帮助:)
存储库是您对持久性策略的抽象。因此,您将在域层中为您的存储库提供一个接口:
interface BoardRepository {
add(Board board);
update(Board board);
delete(BoardId id);
get(BoardId id);
}
如果您将使用 SQL 持久性策略,那么您将在例如您的基础设施层中实现此接口,如下所示。
class SqlBoardRepository implements BoardRepository {
...
}
所以是的,存储库负责持久化聚合。每个聚合将有一个存储库!不是每个实体都有一个存储库!
主键和外键是与数据库相关的主题,通常您在域模型中并不关心它们。域模型中的实体由业务键(也可以用作主键)标识。例如,isbn 标识世界范围内的一本书,它是 Book 实体的业务键,也可以用作数据库中的主键。有时,当在持久性模型中使用业务键过于复杂时,您可以在实体中使用额外的代理键,它主要在持久层上标识您的实体。您使用数据库中的业务或代理键对域对象之间的关系进行建模,并且 sql 存储库负责将域模型映射到数据库,反之亦然。
也许你应该阅读一些关于它,然后你会更好地理解。Eric Evans 的蓝皮书或 Vaughn Vernon 的实施领域驱动设计是一个好的开始 :)
推荐阅读
- uml - 需要帮助阅读 UML 图
- javascript - 我们如何在 firebase 的用户集合中获取文档
- c++ - 测试测量海平面以上水平的 C++ 程序时出现问题
- vba - MSXML2 在 VBA 中返回文件格式 (XML)
- c# - 如何使用 Protobuf 在我的谷歌操作中将字节数组显示为图像?
- python-3.x - 检查 ASCII pyspark 数据帧
- android - 问:无法从对象列表中返回特定属性?
- python - 使用 pandas 从 SQL 表中提取带双引号的数据和不带引号的标题
- python - Requirements.txt 没有在 Azure 应用程序中仅安装“请求”包
- qt - 我不明白为什么我的代码中出现了这个未定义的错误