Should persistent objects validate data across a set?

If you have an object that can persist across all executions (whether it's a DB using an ORM, using something like a Python module shelve

, etc.), should you check the attributes of that object inside the class representing it, or outside?

Or rather; should a persistent object be dumb and expect it to assign values ​​to benevolent, or should it be smart and check the data assigned to it?

I'm not talking about type checking or validating user input, but there are things that affect persistent object like references / references to other objects, ensuring that numbers are unsigned, dates don't go out of bounds, etc.

+2


source to share


3 answers


My policy is that for global code to be reliable, every object A must check as much as possible as early as possible. But "as much as possible" needs an explanation:

  • The intrinsic coherence of each field B in (type, range by type, etc.) must be checked by the type of field B. If it is a primitive field or a reusable class, this is not possible, so object A must check it.
  • the consistency of related fields (if this field B is equal to N, then C must be) is the typical responsibility of object A.
  • In other words, field B coherency with other codes external to the A . This is where the "pojo" approach (in Java, but applicable to any language) comes into play.



The POJO approach says that with all the responsibilities / issues we have in modern software (persistence and validation are just two), the domain model ends up becoming messy and difficult to understand. The problem is that these domain objects are central to understanding the entire application, communicating with domain experts, and so on. Every time you need to read the domain object code, you need to deal with the complexity of all these problems, while you may not care about either one or ...

So, in a POJO approach, your domain objects should not carry code associated with one of these issues (usually an interface to implement or a superclass). All problems except one domain are outside the object (but some simple data can be provided in java, usually via Annotations, to parameterize common external code that handles one problem).

Also, domain objects only refer to other domain objects and not some framework classes related to one issue (like validation or persistence). In this way, the domain model with all classes can be put into a separate "package" (project or whatever), without dependence on technical or related codes. This makes it much easier to grasp the essence of a complex application without all the complexity of these secondary aspects.

0


source


Validation is part of encapsulation - an object is responsible for internal state, and validation is part of internal state.

I like to ask, "Should I let an object execute a function and set its own variables, or should I use it for everyone, do the work in an external function, and then set them back up?"



Of course, you should use the library for most of the validation — you don't want to implement the "check for unsigned values" feature in every model, so you implement it in one place and let each model use it in its own code as required.

+2


source


The object must validate data entry. Otherwise, every part of the application that assigns data must apply the same test suite, and every part of the application that retrieves the stored data must handle the possibility that some other module did not perform its checks as expected.

BTW, I don't think this is an object oriented tang. It applies to any data persistence construct that takes input data. Basically, you are talking about development preconditions by contract.

+1


source







All Articles