贫血领域模型和域名服务

时间:2012-01-06 08:00:41

标签: c# design-patterns service domain-driven-design anemic-domain-model

如果域实体没有贫血,那么他们在自己内部嵌入特定用法行为,是否需要/指向使用/构建特定的域服务?验证应该如何进入实体?

哪种方式对单元测试更灵活?

谢谢!

3 个答案:

答案 0 :(得分:6)

通常,当没有使用贫血模型时,您仍然需要需要特定于域的服务。那是因为非贫血模型(或者只是,模型,如果你愿意)应该包含允许自己被操纵的代码,但是应该避免依赖于其他模型,特别是通过父/子关系不直接相关的模型

单独的域服务将允许您维护该分离并仍然提供丰富的功能,因为它们的域服务可能会意识到整个域模型的更大视图。

至于验证,这些模型提供自己的验证并不罕见,只记得有时模型的有效状态取决于模型可能不知道的更大的上下文,因此外部验证可能仍然存在要存在。

最后,单元测试的灵活性将取决于您的应用程序和底层技术(例如语言选择)。我没有看到很多情况,其中任何一种方法本身都对单元测试有足够的影响。

答案 1 :(得分:2)

拥有域模型时,

Domain Services是必需的,因为有些功能不属于您的实体。

考虑一下RepositoryFactory的例子。 Repository的界面可能位于您的Domain Layer中,但可能位于Infrastructure Layer中。使用Factory,实现和界面都将位于Domain Layer

这些域服务在您的应用层中使用。应用程序层的目标是确保所有内容都到位,以便域模型可以完成其工作。这可能意味着从存储库加载特定实体,然后在它们上调用特定于域的功能。

验证应该进入实体内部。例如,假设您有一个Money类。

public class Money
{
    public Money(string currency, int amount)
    {
        Currency = currency;
        Amount = amount;
    }

    public int Amount { get; set; }

    public string Currency { get; set; }
}

如果Money课程不允许有负数,您会在哪里验证?

最好的地方就是在课堂上。实体负责其自己的州。 在Money课程中,这很容易看到,但例如Order课程OrderLinesOrder负责检查是否有重复的OrderLine应该合并的项目(节省运费!)

答案 2 :(得分:0)

域服务通常包含自然不适合您的某个实体的域功能。它通常是许多其他域对象所需的功能,可能使域服务成为许多对象连接的重要关联。

至于验证,它可以在不同的地方,取决于您想要验证的时间和内容:

  • 工厂在创建实体时强制执行不变量

  • 聚合根强制执行与整个聚合相关的不变量

  • 基本验证通常也在实体内部进行

  • 您可以进行需要与应用程序当前状态相关的数据的自定义验证,在这种情况下,验证更有可能在应用程序层中完成。