Validate What?
I know we've all got our own little validation libraries and approaches, but I'd strongly recommend anyone to check out what Bob's been working on. I haven't had a chance to work with it on a project yet, but I'm hoping to use it on my next project and to get quite involved with the framework as I think it would be great for us to have a nice, elegant validation library that we could then put into larger frameworks for building full stack solutions more quickly while still being able to use it on its own for projects that don't need the other bells and whistles.
Expect to see more about ValidateThis on my blog as I get a chance to play with it. In the meantime, check it out and join the Google group to become part of the conversation.



I find the whole "an object should never be invalid" a little bogus and I find the practical benefits of putting validations in the object wildly outweigh any other concerns I've heard to date. Have you actually ever heard someone come up with a compelling software engineering reason for an object never being instantiated in an invalid state? When I look at the flow of my applications, I don't just load the form scope into a bean, and then forgetting to validate it try to do something it might fail on if it's invalid. Even if I was drunk I don't think I'd do something that silly. Then when I compare that to the benefits of encapsulated validartion and the risks of an anaemic domain model with service classes containing all of the business logic and dumb VO's running round as what is effectively expensive structs, I am quite happy to put the validation within the beans!
The bigger issue which I am dealing with now is that many times you cannot validate a single business object on its own. For example, when a new user profile is created - that user profile is made up of a collection of objects and it would be much easier to validate all of the form submitted data as a unit representing a user profile rather than trying to write validation rules that are interdependent between a collection of objects. For example, a validation rule checking to see if the user has at least one address provided and that there are no duplicates has to deal with the user object and multiple address objects which makes validation at the object level much more complex.
http://www.pbell.com/index.cfm/2009/5/21/The-Impor...
I hear you. In my experience the "if a method was called on the object in an invalid state" is a little bogus just because it's not like I'm just sending my bean all round my app. I have the following code:
User = beanFactory.getBean("User").load(form)
If (User.isValid)
. . .
else
. . .
so there isn't a lot of space for that.
As for the related objects, that all comes down to object composition which is a bit of a pain without a tool like Hibernate to handle all of the joining and persisting and the like, but it;s still a fairly solvable problem in the general case - especially when an object only has sub objects - not sub-sub objects - which covers most common use cases in ColdFusion.
In general, your User.isValid() will include a private User.isValidBillingAddress() method that'll call against the composed BillingAddress.IsValid(), so it's fairly straightforward. The only slightly tricky thing is to write generic code that'll create and populate sub objects from form fields in the general case, but once you get your head around it, it isn't too hard to code.
User = beanFactory.getBean("User").load(form)
rather than calling User.isValid() or some method like that, what if the load() method threw an error or exception that could be caught if the object could not be created with a valid state?
That sounds like a really elegant enhancement. Its mixing both a command and query into a single method call which some people disapprove of, but I find it often creates a cleaner API (my ibo's have a next() method that both increments the iterator pointer and returns a boolean for whether there is a next record). I'll have a think through the implications, but I think I might give that a shot for my next project to see how it works out!
The missing piece here is the notion of the collection object. A business object can be valid in itself, but it may be invalid to add it to a given collection. What you're describing is the validation rules for the collection's "add" method. Those rules may be different for different collections.
To take this a little further, every business object belongs to (at least) the collection of all objects of that type. Thus the idea of instantiating a business object on its own completely disappears. Instead, you ask the "all" collection to create a new object as a member of itself based on some inputs you give it. The collection may, of course, decline. This is exactly analoguous to inserting a record into a table with uniqueness constraints. We don't create a free floating record and then add it to a table.
This approach is kind of hard to do in ColdFusion, and even in Java where the tools definitely exist it's rare. Still, I find it a useful concept to help make sense of the apparent conundrums of validation design.
Great point! I never thought of it that way but I should now since in Flex I'm always working with collections. Everything is very collection driven. You could say the same for CF but I just never thought of it that way since I just used query objects rather than a collection object.
Do you handle your validation within a collection object (adding a new one) or a service object (requesting a collection or a single object)?
Not sure exactly what you mean, but I think the former - collection constraints are handled by the collection. The service is really only used to get a reference to those top-level collections, and maybe for some use-case logic.