Law of Demeter

This tutorial gives you a short explanation of the Law of Demeter. It’s based on a rough chapter draft for my upcoming book “The Art of Clean Code” to appear with NoStarch in 2022.


The Art of Clean Code

Most software developers waste thousands of hours working with overly complex code. The eight core principles in The Art of Clean Coding will teach you how to write clear, maintainable code without compromising functionality. The book’s guiding principle is simplicity: reduce and simplify, then reinvest energy in the important parts to save you countless hours and ease the often onerous task of code maintenance.

  1. Concentrate on the important stuff with the 80/20 principle — focus on the 20% of your code that matters most
  2. Avoid coding in isolation: create a minimum viable product to get early feedback
  3. Write code cleanly and simply to eliminate clutter 
  4. Avoid premature optimization that risks over-complicating code 
  5. Balance your goals, capacity, and feedback to achieve the productive state of Flow
  6. Apply the Do One Thing Well philosophy to vastly improve functionality
  7. Design efficient user interfaces with the Less is More principle
  8. Tie your new skills together into one unifying principle: Focus

The Python-based The Art of Clean Coding is suitable for programmers at any level, with ideas presented in a language-agnostic manner.



Overview

You’ve already learned that one of the most important reasons for code complexity is interdependency. To write clean code, you must minimize the degree of interdependency of your code elements.

Dependencies are everywhere. If you import a module or library in your code, your code depends partially on functionality provided by the library. But your code will not only depend on external sources. There are a lot of interdependencies within your code as well. If you use object-oriented programming, one function may depend on another function, one object may depend on another object, and one class definition on another class definition.

The law of Demeter states that you “only talk to your immediate friends”. The purpose of the law is to minimize the number of dependencies between your code objects. Every object calls only its own methods or methods from “immediate neighbor” objects—it doesn’t call methods of objects it obtains from calling a method.

This may sound confusing at first, so let’s dive into a practical example. Without the Law of Demeter, all three objects know about all other objects. With the Law of Demeter, the Person object knows only about one other object—and doesn’t care about the other one. This decouples the class definitions, reduces complexity, and increases maintainability of your code.

Law of Demeter Example

Figure: Law of demeter—only talk to your friends to minimize dependencies.

The figure shows two object-oriented code projects where your goal is to calculate the price per cup of coffee for a given person. You create a method price_per_cup() that uses the current CoffeeCup object to collect more information about the price of the coffee machine that produced the coffee in the cup—this piece of information is relevant to calculate the price per cup. A bad strategy is given on the left:

  1. The method price_per_cup() calls the method CoffeeCup.get_creator_machine() to get a reference to the object of the coffee machine that created the coffee.
  2. The method get_creator_machine() returns an object reference to the coffee machine that has produced its contents.
  3. The method price_per_cup() calls the method CoffeeMachine.get_price() on the CoffeeMachine object it just obtained from the previous CoffeeCup method call.
  4. The method get_price() returns the original price of the machine.
  5. The method price_per_cup() calculates the depreciation per cup and uses this to estimate the price of a single cup. This is returned to the caller of the method.

Why is this strategy bad?

The reason is that the class Person depends on two objects: CoffeeCup and CoffeeMachine. A programmer responsible for maintaining this class must know about both dependent class definitions—any change in any of those classes may have an impact to this class as well.

The law of Demeter aims to minimize such dependencies. You can see a better way to model the same problem on the right in the figure.

  1. The method price_per_cup() calls the method CoffeeCup.get_costs_per_cup() to get the estimate price per cup based on the coffee cup’s information.
  2. The method get_costs_per_cup()—before replying to the calling method—calls the method CoffeeMachine.get_price() to access the desired pricing information for the whole machine.  
  3. The method get_price() returns the price information.
  4. The method get_costs_per_cup() calculates the price per cup and returns it to the calling method price_per_cup().
  5. The method price_per_cup() simply forwards this calculated value to its caller.

Why is this superior to the first approach? The reason is that the class Person is now independent of the class CoffeeMachine. The total number of dependencies has reduced.

By shielding the complexity from the programmer of the Person class, you’ve made his life much easier. If you have a project with hundreds of classes and you reduce the dependencies through application of the law of Demeter, you can dramatically reduce the overall complexity of your application because the number of potential dependencies grows super-linear in the number of objects. This also means that the law of Demeter has the potential to reduce the number of dependencies super-linearly in the number of objects involved!