Jeff Palermo recently wrote up a blog post about “The fallacy of the always valid entity”. This post is a more thought out commentary to the ideas therein and could be better suited with a name of “The fallacy of the fallacy of the always valid entity”.
Jeff appears to be arguing with something that he for lack of better terminology just does not understand. He gives an example and then asks the question of:
“The fact that name is required needs to be context-bound. When is it invalid?” This is referring to one type of validation that occurs within a domain. This is a validation to perform an operation. Generally speaking this type of validation is not performed by the object itself but is represented as observations of that object by another object. Jeff is right in that trying to make these things always valid makes no sense.
Of course no one in the “always valid object” camp has ever made such a statement. This brings us to the crutch of the argument … What do we want to keep valid?
==?
Not surprisingly some great people have dealt with these problems in the past.We can look at by going into philosophy (yeah boring I know) for a moment. Let’s say there are two horses a big Clydesdale and my friend’s daughter’s pony “samantha”. We have all seen the Budweiser commercials so we can imagine what the Clydesdale looks like but “samantha” is quite different. She is short, kind of thin, white with a black nose, and has her hoofs painted most of the time (likely due to her proximity to my friend’s daughter).
If we were to look at these two things we know that they are both horses. But they are still quite different, why is that? Plato put forth the concept of ideals, that there is somewhere an ideal horse which represents all of the recognizable traits of a horse. All horses can be descended from the one ideal horse, the ideal horse represents all of their common traits.
So you must be thinking how does this relate back to the original topic of objects always being valid? We have introduced a second type of validation!
Suppose we had a unicorn with no horn? Would it still be a unicorn? What about a cyclops with two eyes? These things are invariants of the objects (they belong on the concept of the ideal). If we were to have an object that did not meet these invariants it would in fact cease being the concept that we knew it as.
We run across these types of things regularly in our domains! Let’s imagine we are building grain silos … could we have a grain silo without a capacity? If we were writing poker software could we have a poker table without any seats? For a product application does it make sense to allow a sale line item without a product?
It can be quite useful for us to model our domains using invariants. The main reason for this is that it helps with DRY. Quite often we will see that nearly all or all operations require a certain thing to be true, as such the checks are run in many places. As an example a customer must have a name to place an order, they also must have a name to move, or to open a credit account. We could always be diligent to check that the customer has a name in various contexts or we can build into the customer object the invariant that the name will always be non-null. Invariants help us to narrow our thinking when we rationalize about our domain.
TDD will quickly lead you to the need for invariants. Consider when I have a BattleService that takes a parameter of a Cyclops … Without using invariants the first test I should be writing is should_throw_not_a_cyclops_exception_when_cyclops_has_two_eyes() … As soon as I find myself writing this test I should be seeing the language and realizing that I am being silly. In case that does not work I should at the least see that if I moved such a thing to be an invariant of my object that I could be saving myself code/tests elsewhere.
Now to bring this back to Jeffrey’s original misunderstanding of the always valid viewpoint, it is not that an object must always be valid for everything, there are lots of context based validations… Always valid means that you are not breaking your invariants.
Posted
Fri, May 22 2009 9:08 AM
by
Greg