关于领域驱动设计中的“合法”性校验?

13-04-30 gsft
各位在进行领域驱动设计开发的时候,实体的“合法”性是如何实现的,怎么保证实体的一致合法性?检验代码分布在实体中,还是在服务中,还是都有?如果分布在实体中,如何保证一次性校验,使用构造函数或工厂保证?如何得到校验上下文?有种说法是实体永远有效;另一种则相反,必须经过业务逻辑校验才能算是“合法”实体。大家怎么看?

相关讨论:http://lostechies.com/derickbailey/2009/02/15/proactive-vs-reactive-validation-don-t-we-need-both/

http://lostechies.com/jimmybogard/2009/02/15/validation-in-a-ddd-world/

[该贴被gsft于2013-05-01 10:29修改过]

                   

3
gameboyLV
2013-05-01 10:37
之前是放在服务中,现在是用AOP拦截上下文的Submit事件,未来计划将校验信息存储到数据库中,可通过图像界面配置,并且可以在运行时更改需要拦截的事件,然后执行校验。

jdon007
2013-05-01 17:29
J2EE有针对此问题的规范JSR303,建议在实体中进行合法性的校验。为什么这样做呢?官方给出的理由是:既然在展现层、逻辑层、持久层都需要进行重复的校验,为什么不集中在实体上进行统一的校验,省时省力,多好呀!

显然,这个理由有一定的说服力。但其前提是什么呢?前提是将展现层的事情,在服务端完成;数据的约束,放在持久层完成,也是在服务端完成。

我个人不这么认为,

第一个理由:展现层的约束应该交给应用端,而持久层的约束应该交给数据库(数据表字段的约束设计)。服务端关注业务逻辑上的校验,至于展现约束与存储约束,不是该他做的事情;这样才有利于使业务模型更干净和清晰。(服务端只关注数据与逻辑的处理)

第二个理由:对与错,好与坏,脱离语境(上下文)是不能冒然下定论的,直接将验证逻辑绑定在实体上,无异于直接给一个人贴上好人或坏人,庸才或天才的标签。

你所引用的文章的主要观点,与我的第二个理由相同,支持在业务场景中进行合法性的校验

1)Think about that question, “is this entity valid”. You can’t answer that question unless you know the context for validation.

2)And that’s where I think we should move towards in terms of validation. Instead of answering the question, “is this object valid”, try and answer the question, “Can this operation be performed?”.

此外,合法性的校验是异常设计的一个重要部分,无法回避,甚至需要花不少的精力进行精心的设计。试以最为常见的空指针异常为例,空指针异常是一种运行时异常(unchecked exception),在服务端的校验中时常需要将其包装为编译时异常(checked exception),并在业务场景进行捕获,以响应状态码为400的响应返回应用端;而应用端的空指针异常,则反之,时常仍包装为运行时异常,在最靠近用户的地方捕获该异常,并以友好的提示信息呈现给用户。

当然,如果项目已经采用了服务端的展现框架,比如GWT、JSF、ZK之类的,开发者迫于进度的压力,管它什么干净、清晰的业务模型,按时交工,才是重之重,或许在实体上绑定校验逻辑,是上上之策,这是事实,也很难回避。

gsft
2013-05-02 00:05
非常感谢大家的回复,这个帖子是我第一次在这边发帖;

持久层校验相对单纯;主要是业务逻辑上的校验可能会棘手点,特别是想把业务逻辑的校验封装在实体内部,很多时候会有不一致的情况发生;比如很多个setter必须在一个原子操作中才能满足业务校验规则,如果校验发证在实体中,这个时候又要考虑构造函数、Factory、Builder等等保证一次性创建一个满足业务逻辑要求的实体出来,稍微复杂了些;如果不放在实体中,实体又暴露了setter方法,较难控制其它程序直接调用会造成隐患。

gameboyLV
2013-05-02 07:31
一辆汽车在安装了2个轮子的时候,他就不能叫汽车,只有经过出厂前检测合格了,才是一辆完整的汽车。同样的道理,实体在提交或保存之前都不能叫做实体,所以无需校验。至于何时检验,这个动作应该是被动的,当触发了提交或保存事件时触发。

猜你喜欢
2Go 1 2 下一页