持久对象应该在设置时验证数据吗?

时间:2009-09-09 09:45:57

标签: language-agnostic orm oop persistence

如果有一个对象可以在执行过程中持续存在(无论是使用ORM的数据库,使用类似Python的shelve模块等),那么该对象属性的验证应该放在代表它的类中,还是在外面?

或者更确切地说;持久对象应该 dumb 并期望设置它的值是仁慈的,还是应该智能并验证分配给它的数据?

我不是在讨论类型验证或用户输入验证,而是存在影响持久对象的事情,例如链接/引用其他对象,确保数字未签名,日期不在范围之外等。

3 个答案:

答案 0 :(得分:2)

验证是封装的一部分 - 对象负责其内部状态,验证 是其内部状态的一部分。

这就像问“我应该让一个对象做一个函数并设置他自己的变量,还是我应该让getter得到它们全部,在外部函数中完成工作然后你设置它们来设置它们?”

当然你应该使用库来完成大部分验证 - 你不想在每个模型中实现“检查无符号值”功能,所以你在一个地方实现它,让每个模型在他的模型中使用它自己的代码适合。

答案 1 :(得分:1)

对象应验证数据输入。否则,分配数据的应用程序的每个部分都必须应用同一组测试,并且检索持久数据的应用程序的每个部分都需要处理其他模块未正确完成检查的可能性。

顺便说一下,我不认为这是面向对象的。它适用于任何需要输入的数据持久性构造。基本上,你在谈论按合同设计的前提条件。

答案 2 :(得分:0)

我的政策是,为了使全局代码健壮,每个对象A应尽可能早地检查。但“尽可能”需要解释:

  • A中的每个字段的内部一致性 B(类型,类型范围等)应由字段类型B本身检查。如果它是原始字段或重用类,则不可能,因此A对象应该检查它。
  • 相关字段的连贯性(如果该B字段为空,则C也必须为)是对象A的典型职责。
  • 字段B与A 外部的其他代码的一致性是另一回事。这就是“pojo”方法(在Java中,但适用于任何语言)发挥作用的地方。

POJO 办法说,与所有的责任/顾虑,我们已经在现代软件(持久性和放大器;验证只是其中两个),领域模型最终被凌乱,很难理解。问题是这些域对象对于理解整个应用程序,与域专家进行通信等都至关重要。每次你必须阅读域对象代码时,你必须处理所有这些问题的复杂性,而你可能不关心任何一个或一个......

因此,在POJO方法中,您的域对象不得携带与这些关注点之一相关的代码(通常包含要实现的接口,或者要包含超类)。 除域1之外的所有问题都在对象之外(但是仍然可以通过Annotations在java中提供一些简单的信息来参数化处理一个问题的通用外部代码)。

此外,域对象仅涉及其他域对象,而不涉及与一个关注点(例如验证或持久性)相关的某些框架类。因此,包含所有类的域模型可以放在单独的“包”(项目或其他)中,而不依赖于技术或与关注相关的代码。这使得理解复杂应用程序的核心变得更加容易,而没有这些次要方面的复杂性。