我正在进行一个涉及版本控制实体的项目,以便归档用户修改的整个历史。
基本上,其思想是,当创建实体时,其内容的版本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);
}
}
这是一个好的做法,还是有缺点?到目前为止,我看到的是服务依赖于存储库,而不是相反。
如果按照描述对其进行建模,则会使领域知识隐式,并将其隐藏在存储库中,而存储库本身并不属于领域。我认为这不是一个好主意。
您可以使用域事件对其进行建模,即EntityCreated
。然后,事件侦听器可以获取事件并创建相应的归档条目。
更新以回答评论中提出的问题:
从概念上讲,Repository封装了一组持久化的对象在数据存储和对其执行的操作中,提供持久层的更面向对象的视图--<马丁·福勒>马丁·福勒>
除了形式定义之外:存储库知道如何存储和检索对象。为了能够实现这一点,它需要了解持久性机制,或者至少了解其下的数据访问层。
另一方面,领域模型不应该依赖于外部的任何东西。在端口和适配器体系结构(这比传统的分层方法更适合DDD)中,存储库将是适配器之一。
您的域只知道其存储库的接口,实际实现在外部。通过这种方式,您只有向内指向的依赖项。基本上,这是面向对象的,而具有向下指向、级联依赖关系的分层体系结构更像是一种过程方法。
归档是属于您的普遍语言的领域概念吗?如果是,则应在Domain层中定义ArchiveService
。否则,它可以在基础结构层中定义,IRepository的每个实现都将选择是否存档。
无论如何,我认为依赖于ArchiveService
(或任何其他服务)的Repository没有任何问题。您可以让调用repository.add(entity)
的每一段代码在之后立即调用archiveService.createVersion(entity)
,但这不是很方便。