The Law of Demeter
Reducing the dependencies between classes is a good way to make your code more flexible. The Law of Demeter is a technique that helps with this and reduces coupling between objects. Let’s see how you can apply this to your Ruby code (but remember that these rules apply to any object oriented code).
The Law of Demeter states that when you call a method
bar(x, y) on an object
foo, it should only interact with objects that are closely related to it. The kinds of objects on which
bar can invoke methods are:
- the object
fooitself (ie. any instance methods of
- the arguments of the method
bar(ie. x and y)
- any objects instantiated inside the method
- attributes (instance variables) of
@some_attr.foobar() is OK, but
@some_attr.bar.foobar() are not.
The Paperboy and Wallet Metaphor
The metaphor of a paper boy collecting money from a customer (described in this paper) is an excellent way to understand the Law of Demeter. Imagine a
Paperboy class that must collect money from a
The Paperboy is relying on the knowledge that a customer has a wallet and that it has cash. What happens now if Wallet changes its interface and uses the name
balance instead of
cash? Or adds a bang (
!) to the
#withdraw method to indicate that it changes the state of the wallet?
To avoid this, we could make the Customer responsible for paying, while the Paperboy only knows that Customer has a
Paperboy can simply call
Customer and not have to worry if the money is coming out of a wallet. The customer could be paying with the loose change in their pocket, without reaching for the wallet, and the paper boy doesn’t need to know about that detail.
This isolates the
Paperboy from any changes in
Wallet. If you were to change the internals of
Wallet, it would not have any effect on the other classes. Even if you were to change the interface to
#withdraw, the only change needed would be in
- The Paperboy, the Wallet and the Law of Demeter [PDF]
- Practical Object Oriented Design in Ruby: Interfaces, by Sandi Metz
- Demeter - It’s not just a good idea. It’s the law - article by Avdi Grimm