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