【发布时间】:2012-02-04 00:17:53
【问题描述】:
如果域实体没有贫血,因此它们将特定使用行为嵌入到自身内部,是否需要/点来使用/构建特定域服务?验证应该进入实体内部怎么样?
单元测试哪种方式更灵活?
谢谢!
【问题讨论】:
标签: c# design-patterns service domain-driven-design anemic-domain-model
如果域实体没有贫血,因此它们将特定使用行为嵌入到自身内部,是否需要/点来使用/构建特定域服务?验证应该进入实体内部怎么样?
单元测试哪种方式更灵活?
谢谢!
【问题讨论】:
标签: c# design-patterns service domain-driven-design anemic-domain-model
通常,当不使用贫血模型时,您仍然会有需要特定领域服务的需求。这是因为非贫血模型(或者只是模型,如果你愿意的话)应该包含允许自己被操纵的代码,但应该避免依赖其他模型,尤其是不通过父/子关系直接相关的模型.
独立的域服务将允许您保持这种分离并仍然提供丰富的功能,因为它们的域服务可以潜在地了解整个域模型的更大视图。
至于验证,这些模型提供自己的验证并不少见,请记住,有时模型的有效状态取决于模型可能不知道的更大上下文,因此外部验证可能仍然存在会存在的。
最后,单元测试的灵活性在很大程度上取决于您的应用程序和底层技术(例如语言选择)。我还没有看到很多情况下这两种方法本身对单元测试有足够的影响。
【讨论】:
Domain Services 在您拥有域模型时是必需的,因为存在不属于您的实体的功能。
例如考虑Repository 或Factory。 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 类中,这很容易看到,但例如对于带有OrderLines 的Order 类,Order 负责检查是否有重复的OrderLine 项目应该合并(节省运费! )
【讨论】:
域服务通常包含不适合您的实体之一的域功能。它通常是许多其他域对象所需的功能,可能使域服务成为许多对象连接的大纽带。
至于验证,它可以在不同的地方,具体取决于您想要验证的时间和内容:
工厂在创建实体时强制执行不变量
聚合根强制执行涉及整个聚合的不变量
基本验证也经常在实体本身内部执行
您可以进行自定义验证,该验证需要与应用程序当前状态相关的数据,在这种情况下,验证更有可能在应用程序层完成。
【讨论】: