Monday, June 29, 2009

Demeter's Wrath and Angry Monkeys

Transgressing the Law of Demeter can not only attract the grain goddess' wrath on you but can also turn classes into angry monkeys. Let's see how.

Consider this freshly created method and notice how it asks for more than it needs, setting the stage for the upcoming drama that involves a fuming Demeter in her heavenly spa:

This method needs a country code to perform its unspeakable computation but asks for a User object. Why would anyone do that? Well, if User objects are common goods around the class that holds this method, it may look like a natural thing to do.

Inevitably, methods in other classes will have the need for a schniblitz to be computed for them. They will use the above method and will, therefore, need to provide a User object for them. And they may well be cool with that.

Now enter the angry monkeys. From dependency to dependency, the fact that a User object is needed to compute a schniblitz will get propagated. After a while, once the client call will be far enough from the original method, in another module or project, handled by a different team in another site, no-one will have the slightest clue why a User object is needed. But a barrage of classes will angrily ask for it.

So when an innocent victim comes around, it will be badly beaten if it doesn't present a valid User object in exchange for a nicely computed schniblitz.

But, for this victim, this may well be a big deal. Perhaps, it does not have a full User object handy, so it will need several database calls to completely build it so it can pass it and get its schniblitz. Or perhaps, it deals with NewUser objects, which are the next great things on its side of the world, forcing it to create complex and error-prone object converters in order to turn a NewUser into a User and... get the darn schniblitz!

The kicker is that the innocent victim had a contextually-valid country code. So should the original method had reduced its needs and simply had asked for what it needed, the angry monkeys would have had no "Thou Shalt Provide A User" mantra to sing and life would have been beautiful.

If you find that this whole story sounds too made-up to be true, take a closer look at your code. I bet that, if your code base has a few gray hairs and a bunch of modules, you're more than likely to have a few angry monkeys here and there.

Eek. Eek.


Dom Farr said...

This does sounds all too familiar...oh no! Please say I didn't write the original computeSchniblitz(User user) method.

David Dossot said...

No worries, your honor is safe.

Nick Zhu said...

Good reminder post, thanks David. I still make mistakes like this during refatoring way too often.