BDD / DDD在何处放置基本实体验证的规范?

时间:2009-10-02 16:53:46

标签: nhibernate domain-driven-design bdd

或者,基本实体验证是否被视为规范?

通常,在实际实体中保持基本实体验证(名称不能为空或空,日期必须大于xxx)或在规范中是否更好?

如果在规范中,那会是什么样子?您是否为每个字段都有一个规范,或者将它全部包装在一个EntityIsValid类型规范中?

2 个答案:

答案 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”逻辑就会很棒。

我遇到过两种情况,我们发现自己需要上述解决方案:

  1. 一个典型的响应/请求Web解决方案,其中网页显示保存失败时实体的所有损坏规则。

  2. 从外部更新的数据库中读取模型(因此,尽管有setter逻辑,实体也不是无效的,除非你让你的ORM使用setter,但对我们来说,重点是了解有效性。)