(Updated)I was going to ramble about the best place to do business validations in a java application but I ran into this
post. Todd says it very well. The only place where business logic belongs to such as business validation is in the domain objects. Not in the view, not in the controllers, not to even talk about putting them on facades, services, DTOs or some similar concepts that java community tends to like a lot.
Ruby on Rails shows perfect example of good OOD with putting so elegantly all validations in the model. I struggle with similar concept in java but the situation there was different story. Most of the web frameworks provided some kind of validation in the view/controller part that were too tempting to be used. As a result, we have some of the validations in the view/controller, some in facades/services and sometimes in domain objects. The result is not very impressive. We have a lot of problems and possible defects if we have rich domain objects with a lot of collaboration among them since most of the business logic is placed outside of the domain.
Throwing exceptions in the setters method or much more useful
Notification pattern - domain object use notification object to collect information about errors during validation (implemented similarly in Ruby on Rails) are possible alternatives to have the validations in the model. So, the examples are out there and very convincing.
Then I read the comments in the Todd’s blog and I realize that java community would never get it. Some of the comments are stating that the validations should be separated from the domain objects - preferably in xml file; others point out that putting validations in domain objects make validations not reusable and so on. Similar java thinking could been seen in
this very long discussion in the Spring framework architectural forum about domain objects being bind to the view in a web application is very bad and we have to use DTO and facades. All that was the tipping point for me.
In my previous post “
Learning Ruby on Rails", I wrote that I like java because of the community. It looks like this is not the case any more. I really like the Ruby way of thinking and a very good example is the
Human Interfaces. We can achieve great things with Java as well but the community thinking is not going in this direction, even with frameworks such as Spring built around the principle of simplicity. My only hope is that Ruby would never become the same type of “enterprise” language as Java currently is.
UpdateMartin Flowers’s
ContextualValidation is good addition to the
validation topic.
“But one thing that I think constantly trips people up is when they think object validity on a context independent way such as an isValid method implies.”This is much related to the first comment below:
“…often some of my domain objects will be used across different projects and business rules vary based on the context.”As well as all other similar issues about validation in different user cases, when domain objects are used in batch processing with slightly different business rules and so on.
Martin gives an excellent answer for that:
“I think it's much more useful to think of validation as something that's bound to a context - typically an action that you want to do. Is this order valid to be filled, is this customer valid to check in to the hotel. So rather than have methods like isValid have methods like isValidForCheckIn.”
I subscribe to the view that validation should belong to domain objects like you described. It is more like my domain objects always say they are responsible for validating and making sure data is correct. But the issue I have with this approach is often some of my domain objects will be used across different projects and business rules vary based on the context. Can you suggest a clean approach how to handle this?
Thanks!