【问题标题】:BDD/DDD Where to put specifications for basic entity validation?BDD/DDD 在哪里放置基本实体验证的规范?
【发布时间】:2009-10-02 16:53:45
【问题描述】:

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

一般来说,将基本实体验证(名称不能为空或为空,日期必须大于 xxx)保留在实际实体中还是在规范之外更好?

如果在规范中,那会是什么样子?您会为每个字段制定一个规范,还是将其全部包含在一个 EntityIsValid 类型规范中?

【问题讨论】:

    标签: nhibernate domain-driven-design bdd


    【解决方案1】:

    在我看来,一旦人们对 DDD 有所了解,他们就会选择规范模式并希望将其应用到任何地方。这确实是 Golden Hammer 反模式。

    我认为规范模式的位置以及我理解 Domain-Driven Design 的方式是,当您需要独立于实体改变业务规则时,您可以选择应用这种设计模式。

    请记住,DDD 是一种迭代方法,因此您不必在第一时间就将其“正确”。我将从在实体中进行基本验证开始。这非常符合 OOD 的基本思想,因为它让表示概念的对象知道数据的有效范围。

    在大多数情况下,您甚至不需要显式验证,因为应将实体设计为将约束表示为不变量,从而无法创建违反约束的实例。

    如果您有一条规定 Name 不能为 null 或为空,您可以直接在您的 Entity 中主动强制执行:

    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 类现在不可能进入违反该规则的状态。

    如果稍后您发现规则更复杂,或者在许多不同概念之间共享,您可以随时将其提取到规范中。

    【讨论】:

    • 如果规则稍微复杂一点怎么办,如: ... string Name; //不能在数据库中重复...
    • 由于并发问题,唯一性约束实际上只能在数据库本身中处理。即使您要预先检查唯一性,另一个并发写入也可能在您之前插入完全相同的值。这意味着您不能将唯一性编码为不变量,但您仍然可以通过预先检查来帮助用户。然而,这对我来说不是验证,而是可用性增强。
    【解决方案2】:

    实体同时具有数据和行为,因此让您的实体确保它们的不变量是恕我直言的方法。否则,您可能会得到 anemic domain model [Fowler]。

    如果您的上下文允许您按照 Mark Seemann 的建议在 setter 中强制执行规则,那就太好了,因为您的模型中没有所有“IsValid”和/或“BrokenRules”逻辑。

    我曾在两种情况下发现自己需要上述解决方案:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 2017-01-29
      • 2011-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-22
      相关资源
      最近更新 更多