我正在开展涉及版本化实体的项目,以便存档用户修改的整个历史记录。
基本上,这个想法是当创建实体时,其内容的版本1也保存在存档表中。每当修改实体时,也会存储增量版本。
将实体的状态保存到存档表由ArchiveService
处理。
当实体被持久化时,需要调用ArchiveService来创建版本1,因此最合乎逻辑的方式似乎是从存储库中调用它,从而将服务作为依赖项传递给存储库:
public class Repository {
private ArchiveService archiveService;
public Repository(ArchiveService service) {
this.archiveService = service;
}
public void add(Entity entity) {
// ... (persist the entity)
this.archiveService.createVersion(entity);
}
}
这是一个好习惯,还是有任何缺点? 到目前为止,我看到的是依赖于存储库的服务,而不是反过来。
答案 0 :(得分:3)
如果按照描述对其进行建模,则会隐藏域知识并将其隐藏在存储库中,存储库本身不属于域。我认为这不是一个好主意。
您可以使用Domain Events对其进行建模,即EntityCreated
。然后,事件侦听器可以获取事件并创建相应的存档条目。
更新以回答评论中提出的问题:
从概念上讲,存储库封装了持久化的对象集 在数据存储中以及对它们执行的操作,提供一个 更多面向对象的持久层视图。 - Martin Fowler
除了正式定义:存储库知道如何存储和检索对象。为了能够实现这一点,它需要了解持久性机制或至少下面的数据访问层。
另一方面,域模型不应该依赖于外部的任何东西。在 Ports and Adapters 体系结构(比DDD更适合DDD)中,存储库将是适配器之一。
您的域只知道其存储库的接口,实际的实现在外部。这样你只有内向的依赖。基本上这是面向对象的,而具有向下指向的级联依赖关系的分层架构更像是一种程序方法。
答案 1 :(得分:2)
归档属于您的无处不在语言的域概念?如果是,则应在域层中定义ArchiveService
。否则,它可以在Infrastructure层中定义,IRepository的每个实现都将选择是否存档。
在任何情况下,我都没有看到存储库有任何问题,具体取决于ArchiveService
(或任何其他服务)。您可以随后立即调用repository.add(entity)
调用archiveService.createVersion(entity)
的每一段代码,但这不会非常方便。