Aplicando a lei de Demeter em nossos códigos

     Vinícius B. Alonso

vba321@hotmail.com

Quem sou eu

  • Desenvolvedor Web Pleno                                                          
  • Graduado em Sistemas para Internet (UTFPR)                          
  • Cursando Esp. em Engenharia de Software (PUCPR)                
  • Membro do GURU/PR

Contato

A lei de Demeter

Aprendendo na prática

  • Montando um carrinho de compras                                     
  • Com as classes Produto, Item e Carrinho

Produto

class Product {
  private $value;
  private $name;
    
  public function __construct($name, $value) {
    $this->name  = $name;
    $this->value = $value;
  }
    
  public function getValue() {
    return $this->value;
  }
}

Item

class Item {
  private $product;
  private $quantity;
    
  public function __construct($product, $quantity) {
    $this->product  = $product;
    $this->quantity = $quantity;
  }
    
  public function getProduct() {
    return $this->product;
  }

  public function getQuantity() {
    return $this->quantity;
  }
}

Carrinho

class Cart {
  private $owner;
  private $items;
    
  public function __construct($owner, $items) {
    $this->owner = $owner;
    $this->items = $items;
  }
    
  public function totalValueOfItems() {
    $total = 0;
    foreach ($this->items as $item) {
      $total += $item->getProduct()->getValue() * $item->getQuantity();
    }
    return $total;
  }
}

O que há de errado ?

  • A classe Cart está acessando dados da classe Product sem a conhecer, violando o encapsulamento                    
  • Quem deve retornar o valor de cada produto é a classe Item

 

Carrinho

class Cart {
  private $owner;
  private $items;
    
  public function __construct($owner, $items) {
    $this->owner = $owner;
    $this->items = $items;
  }
    
  public function totalValueOfItems() {
    $total = 0;
    foreach ($this->items as $item) {
      $total += $item->getProduct()->getValue() * $item->getQuantity();
    }
    return $total;
  }
}

Item

class Item {
  private $product;
  private $quantity;
    
  public function __construct($product, $quantity) {
    $this->product  = $product;
    $this->quantity = $quantity;
  }
    
  public function getProduct() {
    return $this->product;
  }
  public function getQuantity() {
    return $this->quantity;
  }
    
  public function totalValue() {
    return $this->product->getValue() * $this->quantity;
  }
}

Carrinho

class Cart {
  private $owner;
  private $items;
    
  public function __construct($owner, $items) {
    $this->owner = $owner;
    $this->items = $items;
  }
    
  public function totalValueOfItems() {
    $total = 0;

    foreach ($this->items as $item) {
      $total += $item->totalValue();
    }

    return $total;
  }
}

Quais as vantagens ?

  • Uso correto do encapsulamento              
  • Evitamos um bad smell chamado Feature Envy                                                

  • Menos lugares para alterar em mudanças futuras

Explicando melhor

  • Foi proposta por Ian Holland em 1987    
  • Recebeu esse nome por ter sido descoberta durante o desenvolvimento do The Demeter Project                              
  • A ideia dela é "converse apenas com seus amigos"

Referências

Aplicando a lei de Demeter em nossos códigos

By Vinícius Alonso

Aplicando a lei de Demeter em nossos códigos

Palestra apresentada no TDC 2017 em Florianópolis.

  • 1,649