3

我正在开发一个涉及版本控制实体的项目,以便归档用户修改的整个历史。

基本上,这个想法是,当创建实体时,其内容的版本 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);
    }
}

这是一个好习惯,还是有什么缺点?到目前为止,我所看到的是依赖于存储库的服务,而不是相反。

4

2 回答 2

3

如果按照描述对其进行建模,您将隐含领域知识并将其隐藏在存储库中,而存储库本身并不是领域的一部分。我认为这不是一个好主意。

您可以使用域事件对其进行建模,即EntityCreated。然后,事件侦听器可以拾取该事件并创建相应的存档条目。

更新以回答评论中提出的问题:

从概念上讲,存储库封装了持久化在数据存储中的一组对象以及对它们执行的操作,从而提供了持久层的更面向对象的视图。——马丁·福勒

除了正式的定义:存储库知道如何存储和检索对象。为了能够做到这一点,它需要了解持久性机制或至少了解其下的数据访问层。

另一方面,域模型不应该依赖于外部的任何东西。在端口和适配器架构中(这比经典的分层方法更适合 DDD)存储库将是适配器之一。

您的域只知道其存储库的接口,实际实现在外部。这样,您只有向内的依赖项。基本上这是面向对象的,而具有向下指向、级联依赖关系的分层架构更像是一种过程方法。

于 2012-11-14T10:53:30.563 回答
2

Is Archiving a domain concept that belongs to your Ubiquitous Language ? If it is, ArchiveService should be defined in the Domain layer. Otherwise, it can be defined in the Infrastructure layer and each implementation of IRepository will choose whether they archive or not.

In any case, I don't see anything wrong with a Repository depending on ArchiveService (or any other service). You could have every piece of code calling repository.add(entity) call archiveService.createVersion(entity) immediately afterwards, but it wouldn't be very convenient.

于 2012-11-14T14:25:45.700 回答