There have been some good discussion lately around the Law of Demeter. The worst thing about Law of Demeter is that it has the word “Law” in it. Like all of the SOLID principles, it should be considered a rule of thumb and your experience and knowledge of the domain should tell you when it it appropriate. However, I would consider staying consistent with this principles (as with all of the others) the starting point and transgress only under special circumstances.
If you haven’t heard of Demeter, the formal definition is that methods of a given class should only access:
- Fields and Methods on the object.
- Any object created within the method.
- Any direct properties or methods of an argument to the method
By following Demeter, you have stronger encapsulation in your objects. This will lead to fewer coupling points in your application and thereby lowering coupling in your system. When you do violate this principle it is easy to get into the situation where a change in one part of system has repercussions in other parts that were not touched for a specific release. That’s when your day after release becomes a nightmare of chasing down bugs in production you can’t explain.
Recently I was was brought on to a very large application that has been in development for over a year. When pairing with one the devs on a new feature, the implementation he proposed broke Demeter in several places, accessing child properties and methods a few levels deep. When I brought this to his attention and explained to him that if you’re absolutely sure the object in question will always be created with the Properties in question, then you can considerate an allowable break of the rule.
The developer I was partnering did not think it was possible to construct the object in which this violation would ever cause a problem. He’s a smart guy and I have no reason to doubt him, but as the title of of this post states, change is the one true constant. We know that requirements change over time. We also know that end users are very creative in using applications for solving problems they are not designed for.
Staying consistent with Demeter is my default way of developing new features. Even if I think the chances of getting into an invalid state are infinitesimal, I still try to stay consistent with this principle. It gives me greater flexibility to change the system as necessary and keeps my dependencies to getting to “sticky”, where I have to worry about who is accessing a property inappropriately when it is time to change them.