The Law of Demeter

Simplifying Object Communication

Posted by Martín Peveri on February 10, 2024 · 3 mins read

The Law of Demeter

Simplifying Object Communication

The Law of Demeter, also known as the Principle of least knowledge, is a software design principle that promotes encapsulation and reduces coupling between objects. This principle states that an object should have limited knowledge about other objects and should only communicate with its "closest" friends. In simpler terms, an object should not have to "know" too much about the internal structure of other objects to perform its function.

What is the Law of Demeter?

The Law of Demeter can be expressed as follows:

"An object should have access only to its own fields, the parameters it receives in its method calls, objects it creates internally, and objects passed in as method arguments."

This means that an object should not navigate through a chain of calls to interact with indirectly related objects. Instead, it should delegate that responsibility to closer objects.

Implementation

In this case I am going to show the example in Typescript:


  class Person {
    private name: string;
    private address: Address;
  
    constructor(name: string, address: Address) {
      this.name = name;
      this.address = address;
    }
  
    getName(): string {
      return this.name;
    }
  
    getAddress(): Address {
      return this.address;
    }
  }
  
  class Address {
    private street: string;
  
    constructor(street: string) {
      this.street = street;
    }
  
    getStreet(): string {
      return this.street;
    }
  }
  
  const address = new Address('Main Street');
  const person = new Person('John', address);
  
  console.log(person.getAddress.getStreet());
  
In this case we are breaking the law of demeter, to fix it:

class Person {
  private name: string;
  private address: Address;

  constructor(name: string, address: Address) {
    this.name = name;
    this.address = address;
  }

  getName(): string {
    return this.name;
  }

  getStreet(): Address {
    return this.address.getStreet();
  }
}

class Address {
  private street: string;

  constructor(street: string) {
    this.street = street;
  }

  getStreet(): string {
    return this.street;
  }
}

const address = new Address('Main Street');
const person = new Person('John', address);

console.log(person.getStreet());

As we can see, we get the street from a method called getStreet from the Person class; this internally calls a getStreet method from the Address class.

Benefits of the Law of Demeter

  1. Decoupling: By following the Law of Demeter, coupling between objects is reduced, making code maintenance and modification easier.
  2. Encapsulation: Data encapsulation is promoted by limiting direct access to other objects' fields.
  3. Readability: Code becomes more readable and understandable since dependencies between objects are reduced, and clearer and more direct communication is encouraged.

Conclusion

By following the Law of Demeter your code will be more modular and flexible, leading to a more robust and maintainable software design.