或者,基本实体验证是否被视为规范?
通常,在实际实体中保持基本实体验证(名称不能为空或空,日期必须大于xxx)或在规范中是否更好?
如果在规范中,那会是什么样子?您是否为每个字段都有一个规范,或者将它全部包装在一个EntityIsValid类型规范中?
答案 0 :(得分:4)
在我看来,一旦人们对DDD有了一点了解,他们就会选择规范模式,并将其应用到各处。那就是 Golden Hammer 反模式。
我看到规范模式的位置以及我理解Domain-Driven Design的方式的方式是,当您需要独立于实体更改业务规则时,它可以选择应用的设计模式。
请记住,DDD是一种迭代方法,所以你不必在第一次采取时“正确”。我首先将基本验证放在实体中。这非常符合OOD的基本思想,因为它可以让代表概念的对象了解有效的数据范围。
在大多数情况下,您甚至不需要显式验证,因为实体的设计应使约束表示为不变量,从而无法创建违反约束的实例。
如果您的规则指出Name不能为null或为空,您可以直接在您的实体中主动强制执行:
public class MyEntity
{
private string name;
public MyEntity(string name)
{
if(string.IsNullOrEmpty(name))
{
throw new ArgumentException();
}
this.name = name;
}
public string Name
{
get { return this.name; }
set
{
if(string.IsNullOrEmpty(value))
{
throw new ArgumentException();
}
this.name = value;
}
}
}
name不能为null的规则现在是该类的不变量:MyEntity类现在不可能进入该规则被破坏的状态。
如果稍后您发现规则更复杂,或者在许多不同概念之间共享,您始终可以将其提取到规范中。
答案 1 :(得分:1)
实体既有数据又有行为,因此让您的实体确保其不变量是恕我直言的方式。否则,你最终可能会得到一个anemic domain model [福勒]。
如果你的上下文允许你像Mark Seemann所建议的那样强制执行setter中的规则,那么你的模型中没有所有“IsValid”和/或“BrokenRules”逻辑就会很棒。
我遇到过两种情况,我们发现自己需要上述解决方案:
一个典型的响应/请求Web解决方案,其中网页显示保存失败时实体的所有损坏规则。
从外部更新的数据库中读取模型(因此,尽管有setter逻辑,实体也不是无效的,除非你让你的ORM使用setter,但对我们来说,重点是了解有效性。)