相关讨论: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修改过]
http://lostechies.com/jimmybogard/2009/02/15/validation-in-a-ddd-world/
[该贴被gsft于2013-05-01 10:29修改过]
显然,这个理由有一定的说服力。但其前提是什么呢?前提是将展现层的事情,在服务端完成;数据的约束,放在持久层完成,也是在服务端完成。
我个人不这么认为,
第一个理由:展现层的约束应该交给应用端,而持久层的约束应该交给数据库(数据表字段的约束设计)。服务端关注业务逻辑上的校验,至于展现约束与存储约束,不是该他做的事情;这样才有利于使业务模型更干净和清晰。(服务端只关注数据与逻辑的处理)
第二个理由:对与错,好与坏,脱离语境(上下文)是不能冒然下定论的,直接将验证逻辑绑定在实体上,无异于直接给一个人贴上好人或坏人,庸才或天才的标签。
你所引用的文章的主要观点,与我的第二个理由相同,支持在业务场景中进行合法性的校验:
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之类的,开发者迫于进度的压力,管它什么干净、清晰的业务模型,按时交工,才是重之重,或许在实体上绑定校验逻辑,是上上之策,这是事实,也很难回避。
说得很好,我认为这实际就是逻辑一致性的问题。实现上通过规格约束Specification来指定实体创造必须符合某种规格要求。这样,实体和规格类等附件组合成了一个聚合。符合聚合保证逻辑一致性的设计原则。
另外我想对DRY(不要重复你自己)原则说几句,这个原则应该置于逻辑一致性之下,只是一个战术性原则,经常因为自己的眼界和角度问题,使用DRY原则形成新的紧耦合,一只青蛙每天在井底下看到一片天,它就把天抽象为一个类,那个类的边界大小只有井口那么大,如果它跳出井,就发现原来为了不重复而抽象出类的细腻度和边界都是有问题的。
相关主题:
迪米特法则(Law of Demeter)与领域模型行为:
http://www.jdon.com/45378
[该贴被banq于2013-05-05 13:30修改过]