【问题标题】:DDD, Repositories and Role InterfacesDDD、存储库和角色接口
【发布时间】:2011-05-19 14:22:07
【问题描述】:

我非常感谢人们对以下设计问题的意见。

我有一个模型,其中“个人”或“企业”可能是某个“服务”的提供者。示例类定义如下所示:

IProvider
Guid Id

人员:IProvider
Guid Id
string FirstName
string LastName

业务:IProvider
Guid Id
字符串名称

服务
Guid Id
IProvider 提供者

因此,我在我的领域中创建了相关概念,“Person”、“Business”、“IProvider”和“Service”。我正在努力的地方是创建存储库的实体。在这种情况下,“服务”是一个聚合根,因此有自己的存储库。在我的上下文中,“业务”也是一个聚合根,因为即使它不是提供者,它也会有意义。 “Person”只有在“是 Provider”时才会在系统中创建。

我会为 IProvider 的角色创建一个存储库,它会返回“Person”和“Business”的实例吗?我的问题是代码可能很快变得非常复杂,因为任何实现都需要查看多个表等以返回所有不同类型的 IProvider。这种方法需要为“Person”和“Business”创建存储库并将其注入“IProvider”存储库以提供所需的功能,即

public class ProviderRepository : IProviderRepoistory
{
    public IBusinessRepository businessRepository {get; set; }
    public IPersonRepository personRepository {get; set; }

    public IProvider FindById(Guid Id){
        IProvider entity = businessRepository.FindById(Id);

        if(entity == null)
            entity = personRepository.FindById(Id);

        return entity;
    }
}

另一种方法是为实现“IProvider”接口的“Person”和“Business”实体创建存储库,从而使它们可以参与该角色。即

public class PersonRepository : IPersonRepository, IProviderRepository
{
    private ISession session;        

    public Person FindById(Guid Id){
        return session.Query<Person>().FirstOrDefault<Person>(x => x.Id == Id);
    }

    public IProvider FindById(Guid Id){
        return session.Query<Person>().FirstOrDefault<Person>(x => x.Id == Id && x.IsProvider == true);
    }
}

然后,我会在需要时使用机制(即 IoC 容器)来选择 IProviderRepository 的正确具体实现。例如,如果我正在与我知道是个人的提供者打交道,我可以获得 PersonRepository 实现。

另一种选择是不实施任何 IProvider 存储库,只使用“Person”和“Business”存储库并在服务层中根据需要使用它们?

【问题讨论】:

    标签: nhibernate domain-driven-design roles ddd-repositories


    【解决方案1】:

    我认为你想多了,而且你试图过早地优化。

    从您在这里所说的一切来看,在我看来,Person 和 Business 都是实体,但两者都不是聚合体(尽管很明显,我可能在您与领域专家的讨论中遗漏了一些东西)。在我看来,提供者是聚合体。

    当您构建 ProviderRepository 时,您不需要为企业和人员注入存储库,b/c 如果它们不是聚合,则它们不应该有自己的存储库。相反,ProviderRepository 应该直接使用 Session 从您想出的任何 DB 模式中获取它需要的内容,以组合给定查询的相关实体。如果您正确映射继承,您可以在基类或接口上进行查询。

    【讨论】:

    • 感谢保罗的cmets。在我的情况下,业务实体将在系统中使用,即使它不是提供者。例如,域用户将在系统中维护业务记录,此时其中的一部分可能会成为提供者。
    • 我同意你关于过早优化的观点。在我的项目中,数据源可能是云服务而不是部分域的数据库,因此我无法利用 nhibernate 的“任意”功能来自动查找实现给定接口的所有实体;因此我开始思考如何优化 IProvider 存储库如何找到数据的来源,即检查什么类型。
    • 很公平,只是要小心早期的优化陷阱。关于在系统中使用但不作为提供者的业务实体,请考虑将限界上下文作为一种思考方式。 markhneedham.com/blog/2009/03/07/ddd-bounded-contexts
    • 感谢 Paul 的链接,我会做更多关于 BC 的研究。
    猜你喜欢
    • 2012-09-15
    • 1970-01-01
    • 1970-01-01
    • 2013-12-05
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多