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,850