domain-driven-design - DDD工厂责任

标签 domain-driven-design factory-pattern ddd-repositories

如果有以下代码。

public class CountryFactory : IEntityFactory
{
    private readonly IRepository<Country> countryRepository;

    public CountryFactory(IRepository<Country> countryRepository)
    {
        this.countryRepository = countryRepository;
    }

    public Country CreateCountry(string name)
    {
        if (countryRepository.FindAll().Any(c => c.Name == name))
        {
            throw new ArgumentException("There is already a country with that name!");
        }

        return new Country(name);
    }
}

从 DDD 方法来看,这是创建国家的正确方法。或者最好有一个 CountryService 来检查一个国家是否存在,如果不存在,只需调用工厂返回一个新实体。这意味着服务将负责持久化实体而不是工厂。

我有点困惑,不知道责任应该在哪里。特别是如果需要创建更复杂的实体,这不像创建一个国家那么简单。

最佳答案

在 DDD 中,工厂用于封装复杂对象并聚合创建。通常,工厂不会实现为单独的类,而是实现为返回新聚合的聚合根类上的静态方法。

工厂方法比构造函数更适合,因为您可能需要具有用于序列化目的的技术构造函数,并且 var x = new Country(name) 在您的通用语言中没有什么意义。这是什么意思?为什么创建国家时需要名字?你真的创造了国家吗?新国家出现的频率如何?你是否需要对这个过程进行建模?如果您开始考虑除了战术模式之外的模型和通用语言,所有这些问题都会出现。

工厂必须返回有效的对象(即聚合),检查其内部的所有不变量,但不检查外部。工厂可能会接收服务和存储库作为参数,但这也不是很常见。通常,您有一个应用程序服务或命令处理程序来执行一些验证,然后使用工厂方法创建一个新聚合并将其添加到存储库中。

Lev Gorodinski 这里也有一个很好的答案 Factory Pattern where should this live in DDD?

此外,Red Book 的第 11 章详细描述了工厂的实现。 .

关于domain-driven-design - DDD工厂责任,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35786019/

相关文章:

asp.net-mvc - 流畅的验证、域和 View 模型

domain-driven-design - 通过多个聚合从域事件重建查询

java - 带有泛型的工厂模式

typescript - 如何使用父静态方法在 TypeScript 中创建子类?

domain-driven-design - DDD 中聚合的不同持久性存储库

c# - 在 DDD 中打包存储库及其接口(interface)

java - Spring Data 存储库是如何实际实现的?

c# - 如何为分层数据结构定义 DDD 聚合根?

domain-driven-design - 为什么允许在稍后的某个时间强制执行跨聚合的一致性规则?

python - 对象生成器模式