【问题标题】:Is it ok to have a Repository depending on a Service?可以根据服务拥有一个存储库吗?
【发布时间】:2012-11-14 10:38:13
【问题描述】:

我正在处理一个涉及版本控制实体的项目,以便将用户修改的整个历史记录存档。

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

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

【问题讨论】:

    标签: domain-driven-design


    【解决方案1】:

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

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

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

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

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

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

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

    【讨论】:

    • 我一直认为存储库是域的一部分。你有这方面的资料吗?
    【解决方案2】:

    归档是属于您的通用语言的域概念吗?如果是,ArchiveService 应该在域层中定义。否则,可以在 Infrastructure 层中定义,IRepository 的每个实现都会选择是否归档。

    无论如何,我认为依赖于ArchiveService(或任何其他服务)的存储库没有任何问题。您可以让每段代码都调用repository.add(entity) 之后立即调用archiveService.createVersion(entity),但这不是很方便。

    【讨论】:

    • 是的,它是通用语言和领域模型的一部分,我们希望能够搜索和显示存档,查看谁做了什么,等等。
    猜你喜欢
    • 1970-01-01
    • 2015-08-31
    • 2015-01-11
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多