Self-validaing domain objects, part two

June 22, 2009

In my earlier discussion of self-validating domain objects, I left open the issue of distinguishing between an initialized and an uninitialized instance of a domain object, and some of the problems created by this difference. I have given it some further thought, and it occurred to me that I was making a common fundamental error in my judgement: I was applying a design pattern for the pattern's sake.

It is easy to fall into the trap of manipulating any given problem so that it fits within the constraints of a particular design pattern, because it matches what we know, and makes sense based on what we already understand. While design patterns are certainly a powerful tool understanding, applying, and communicating common methodologies, they are not always a silver bullet. It reminds me of the saying about how everything looks like a nail to a person carrying a hammer.

In this case, the pattern I was blindly adhering to is the familiar JavaBean pattern. I fell into the trap of thinking about dependency injection (specifically setter injection), how my beans would fit into a Spring context, and how POJOs with constructor arguments can get quite nasty, especially when they have lots of similarly-typed properties.

I have since reconsidered the application of the JavaBean pattern to self-validating domain objects, and realized that the issue of whether or not an instance of a domain object has been initialized can be easily eliminated. If I simply define that all self-validating domain objects must have exactly one constructor which takes arguments for each of its properties and performs the same validation as in the setters (perhaps just by calling the setters), there ceases to be a need for a domain object to implement InitializingBean, FactoryBean, or Initializable, and there ceases to be a need to even define Initializable in the first place. With this pattern, there is no longer the possibility that an instance of a domain object can exist in an invalid state.