Back when we put together Validat, one of the topics of discussion was whether validation should occur at the object level or at the data level (i.e. a collection of user submitted data). This topic came up again last week on Ben Nadel’s blog with his postings regarding his class experience with Hal Helms. The comment Ben made that really got me thinking again was ….
An object can only ever exist in a valid state. An object should never be created or allowed to enter a state that is not valid within the domain.
While his discussion of Human and Vehicle objects is nice and illustrates the point fairly well, most times with web applications, we are dealing with a much more “data centric” scenario for lack of a better word. A lot of the functionality we are building is fairly basic CRUD … reading and writing data. So, lets take a shopping cart for example. A shopping cart has a Product object and that Product object is fairly simple containing basic data like a name, description, picture, etc. From the administration interface when the shop owner is creating and editing products, they have a simple form to enter this data. They submit the form and then what? Obviously the submitted data needs validating, but how?
To slip off topic for a second, Ben’s posting seems to hint that he and/or Hal are advocating putting the form level validation into the controller of the application. This is one of those areas where it is probably more personal opinion rather than right vs. wrong, but I am still of the belief that the controller layer of an application should merely be the traffic cop in the intersection guiding bits of information from point A to point B and not really doing anything more.
In one of the projects we are currently working on, the top most service layer has a saveProduct() method on it to keep with our example. This method simply takes a collection of data and then using Validat, validates that collection of data against a set of rules to see if it represents a valid object. At no point have we created a business object to do this validation. If the data collection is valid, then the business object is populated and passed on to various functions within the application model for processing. If the data collection is invalid, then a collection of errors is returned to the controller and thus the controller simply has to check the result of the saveProduct() method call and based upon that result, redisplay the form and display a save confirmation message to the user.
So, to bring this back to the question at hand, even though we put it into Validat, I still see no reason why you would ever want to stuff potentially invalid data into a business object. Not only does this potentially not represent a valid business object, but it requires you to do away with some of the basic type and validation checking of arguments on your get/set methods in order to allow any data to be put into that business object. It just seems much cleaner to validate the user submitted data at the top most service layer (not the controller) and then if valid, create and populate the business object.
Comments on: "Data Validation vs. Object Validation" (3)
I get the point to your argument, but isn’t it more abstract than applied? People may come up with one argument about where your thoughts apply and another would give a application where they feel it wouldn’t apply. Note that I agree with your basic concept but that doesn’t mean your complete concept is something that seems to be an absolute bad thing. It seems to be something that can work both ways but there are advantages to doing things before the business object. (With that said… it sure would be nice if we had a real object persistence vs persisting our objects via relational databases.)
In Transfer, assuming “bean” and “object” are the same for the moment, you’re never supposed to alter the primary data bean, but rather clone() it first. This allows you to have an object that is dirty, but still allow you to use an object and all it’s functions without modifying the “real” object.
I personally think that it’s foolish to allow bad data into your model, period. It’s thinking like this that has allowed things like SQL injection attacks to proliferate in the first place, and just because there’s minimal risk of an attack like that in this case doesn’t mean that, somehow, the best practice changes.
Seriously, the whole notion of allowing your controller to pass invalid data to your model escapes me. It doesn’t even make sense.