如果域实体没有贫血,那么他们在自己内部嵌入特定用法行为,是否需要/指向使用/构建特定的域服务?验证应该如何进入实体?
哪种方式对单元测试更灵活?
谢谢!
答案 0 :(得分:6)
通常,当没有使用贫血模型时,您仍然需要需要特定于域的服务。那是因为非贫血模型(或者只是,模型,如果你愿意)应该包含允许自己被操纵的代码,但是应该避免依赖于其他模型,特别是通过父/子关系不直接相关的模型
单独的域服务将允许您维护该分离并仍然提供丰富的功能,因为它们的域服务可能会意识到整个域模型的更大视图。
至于验证,这些模型提供自己的验证并不罕见,只记得有时模型的有效状态取决于模型可能不知道的更大的上下文,因此外部验证可能仍然存在要存在。
最后,单元测试的灵活性将取决于您的应用程序和底层技术(例如语言选择)。我没有看到很多情况,其中任何一种方法本身都对单元测试有足够的影响。
答案 1 :(得分:2)
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
课程中,这很容易看到,但例如Order
课程OrderLines
,Order
负责检查是否有重复的OrderLine
应该合并的项目(节省运费!)
答案 2 :(得分:0)
域服务通常包含自然不适合您的某个实体的域功能。它通常是许多其他域对象所需的功能,可能使域服务成为许多对象连接的重要关联。
至于验证,它可以在不同的地方,取决于您想要验证的时间和内容:
工厂在创建实体时强制执行不变量
聚合根强制执行与整个聚合相关的不变量
基本验证通常也在实体内部进行
您可以进行需要与应用程序当前状态相关的数据的自定义验证,在这种情况下,验证更有可能在应用程序层中完成。