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.
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.
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 {
constructor(private street: string, private zip: string) {}
getStreet(): string {
return this.street;
}
getZip(): string {
return this.zip;
}
}
const address = new Address('Main Street');
const person = new Person('John', address);
console.log(`${person.getAddress().getStreet()}, ${person.getAddress().getZip()}`);
In this case, we are breaking the Law of Demeter because we are exposing the Address class. 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;
}
location(): string {
return this.address.getFormattedAddress();
}
}
class Address {
constructor(private street: string, private zip: string) {}
getFormattedAddress(): string {
return `${this.street}, ${this.zip}`;
}
}
const address = new Address('Main Street');
const person = new Person('John', address);
console.log(person.location());
As we can see, we get the street from a method called location from the Person class; this internally calls a getStreet and getZip methods from the Address class.
Another important thing is not to expose unnecessary internal details in the naming. We need to focus on behavior based on the needs of the clients."
By following the Law of Demeter your code will be more modular and flexible, leading to a more robust and maintainable software design.