The Law of Demeter

The Law of Demeter is a guideline that can help your code to be stable and simple. It is also known as the principle of least knowledge, a name that was given by the basic rules that a programmer must follow to comply to the Law of Demeter.

A method M of an object O should only call methods on the following:

  • O itself (i.e., call its own methods)
  • Objects passed in as arguments to M
  • Objects created/instantiated within M
  • Direct component objects (fields) of O (i.e., objects that are directly owned by O)

Breaking the law

The most common practice to break the law is the by chained calls like:


obj.getA().getB().doSomething()
                                        

The above example creates a tight coupling with the internal structure of objects that make your code more fragile.


Good Example


class Wallet:
    def __init__(self, balance):
        self._balance = balance

    def get_balance(self):
        return self._balance


class Customer:
    def __init__(self, wallet):
        self._wallet = wallet

    def get_balance(self):
        return self._wallet.get_balance()  # OK: direct field

                                        

Bad Example


class Money:
    def __init__(self, amount):
        self._amount = amount

    def get_amount(self):
        return self._amount


class Wallet:
    def __init__(self, money):
        self._money = money

    def get_money(self):
        return self._money


class Customer:
    def __init__(self, wallet):
        self._wallet = wallet

    def get_wallet_amount(self):
        return self._wallet.get_money().get_amount()
        # ❌ Too many hops

                                        

Fix by Delegation (Follows LoD)


class Money:
    def __init__(self, amount):
        self._amount = amount

    def get_amount(self):
        return self._amount


class Wallet:
    def __init__(self, money):
        self._money = money

    def get_amount(self):
        return self._money.get_amount()  # Delegation


class Customer:
    def __init__(self, wallet):
        self._wallet = wallet

    def get_wallet_amount(self):
        return self._wallet.get_amount()
        # ✅ One-level call

                                        

It is obvious that a simplified version of the Law of Demeter rules could be that an object only talks to his friends, never to strangers and its object must have a limited knowledge about other objects, only the objects that are closely related to it.