Law of Demeter in PHP

Principle of Least Knowledge

The Law of Demeter is a design guideline with as goal to create loose coupling between objects. If an object knows too much about another (knowledge how to access the third object from the first object) is considered as bad design, because the object has to unnecessary traverse from top to bottom of the chain to get actual dependencies it needs to work with.

  • A method of an object can call methods of that object
  • A method can call a method of its parameters
  • A method can call a method of any objects created or instantiated by that method
  • A method can call a method of objects that are dependencies of the methods object
  • A method can call a method of a global variable that is accessible by the object of the method

The One Dot Principle Violation

class InvoiceController
{
    public function create(User $user, $invoiceTotal)
    {
        try {
            $user->getAccount()
                ->getBalance()
                ->substractSum($invoiceTotal);
        } catch (Exception $e) {
            // handle expcetion
        }
    }
}

This introduces tight coupling, which we should always be trying to avoid in our codebase. Tight coupling reduces the quality of our application code, making it harder to maintain. When we modify one piece of tightly coupled code, then when need to review and modify all the other members of the tightly coupled relationships.

class InvoiceController 
{
    use App\User;
    use App\Invoice;

    public function __construct(User $user, Invoice $invoice){
        $this->user = $user; 
        $this->invoice = $invoice;
    }

    public function processPayment()
    {
        try {
            $this->user->payInvoice($this->invoice);
            // The other methods getAccount(), getBalance() and substractSum($invoiceTotal)
            // will be handled in there own class/methods NO CHAINING
        } catch(Exception $e) {
            // handle exception
        }
    }
}

The knowledge of the inner process of the invoice payment now is encapsulated in User class. The Law of Demeter gives us a guideline how to achieve loose coupling in our code and helps to properly encapsulate the knowledge of some complicated operations or logic into the places where they should be.