Igor's Blog

"... no matter what they tell you, it's always a people problem!"

Wednesday, December 07, 2005

My Ruby Tipping Point

(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.

Update

Martin 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.”

|| Igor, Wednesday, December 07, 2005

3 Comments:

Developer seeking guidance or ideas.

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!
Anonymous Anonymous, at December 07, 2005 9:39 AM  
I had a similar epiphany coming from ASP.Net. ASP.Net has some nice validation server controls for the views that are very tempting to use.

Seeing how Rails puts that logic in the model makes a lot more sense. You can now reuse your validations everywhere the model is just used, not just the one or two forms it's a part of.

Regarding comment #1: there's isn't much sharing of domain objects across projects in ruby on rails. Each project has its own domain models with their own validations and other business rules. Common logic can easily be refactored out into acts_as_* plugins or mixins as well.
Anonymous Anonymous, at December 07, 2005 10:04 AM  
I think the trick is to have the validation rules in the domain model, but have the validation applied in the view and the controller, such that users can get instant feedback as they type into a form, and that controllers can call the validation code and redirect people to the appropriate location when validation fails.

In Struts, I always had the Struts Validation delegate to the domain objects at the controller level, but it was difficult for this to flow all of the way down to the html form.
Blogger Matt McKnight, at December 08, 2005 10:33 AM  

Add a comment