Introducción
En este artículo vamos a ver qué es la Ley de Demeter, un principio muy
útil a la hora de no tener acoplamiento de código relacionado a la estructuración de nuestras clases.
¿Qué es la Ley de Demeter?
La Ley de Demeter (o Ley de No Hables con Extraños) fue introducida por Ian Holland en el año 1987 en la Universidad de Northeastern.
Es un principio enfocado a promover un bajo acoplamiento y una alta cohesión entre las clases de nuestro sistema.
El nombre de la ley viene de la mitología griega, concretamente de la diosa de la agricultura. Se interpreta como una
metáfora al crecimiento saludable y bien estructurado del software donde cada semilla (clase) se desarrolla de forma
independiente sin crear dependencias innecesarias.
La Ley de Demeter está estrechamente relacionada con los principios del Software Craftsmanship. Muchos la consideran como la sexta regla de los [principios SOLID]({{< ref «/posts/principios-solid» >}}).
Un método de una clase solo debe llamar a métodos de:
- La propia clase.
- Objetos que se pasan como parámetros.
- Objetos que se crean dentro de la clase.
- Objetos de variables de instancia.
Un método no debería llamar a métodos de objetos que se devuelven de otros métodos (chaining methods).
Ejemplo práctico de la Ley de Demeter
Vamos a ver un ejemplo práctico de cómo aplicar la Ley de Demeter en nuestro código.
Primero vamos a ver un ejemplo que viola la Ley de Demeter:
class Money {
public function getAmount();
}
class Discount {
public function getPercentage();
}
class InvoiceLine {
public function getMoney(): Money;
public function getDiscount(): Discount;
}
class Invoice {
private array $lines;
public function getTotalPrice(): float
{
$total = 0;
foreach($lines as $line) {
$total += ($line->getMoney()->getAmount() - ($line->getMoney()->getAmount() * $line->getDiscount()->getPercentage() / 100));
}
}
}
Como podéis ver en el ejemplo, para calcular el precio total de una factura se está accediendo directamente a métodos de objetos
que se encuentran dentro de otros objetos violando la Ley de Demeter.
Ahora vamos a ver cómo lo podríamos refactorizar para cumplir con la Ley de Demeter:
class Money {
public function getAmount();
}
class Discount {
public function getPercentage();
public function applyDiscount(float $amount): float {
return $amount - ($amount * $this->getPercentage() / 100);
}
}
class InvoiceLine {
public function getPrice(): float {
$amount = $this->getMoney()->getAmount();
return $this->getDiscount()->applyDiscount($amount);
}
}
class Invoice {
private array $lines;
public function getTotalPrice(): float
{
$total = 0;
foreach($lines as $line) {
$total += $line->getPrice();
}
}
}
Como podéis ver, hemos creado un método applyDiscount
en la clase Discount
que se encarga de aplicar el descuento
a un precio, además hemos creado un método getPrice
en la clase InvoiceLine
que se encarga de calcular el precio
de una línea de factura aplicando el descuento, lo que hace que la clase Invoice
no tenga que acceder a métodos de
objetos que se encuentran dentro de otros objetos.
Hay que tener cuidado con la Ley de Demeter ya que en ocasiones puede llevar a la creación de métodos que no tienen
sentido en la clase, por lo que es importante encontrar un equilibrio entre cumplir con la Ley de Demeter y no crear
métodos que no tienen sentido en la clase.
Las soluciones a los problemas de la Ley de Demeter suelen ser muy específicas a cada caso, por lo que es importante
analizar cada caso concreto para encontrar la mejor solución.
Conclusiones
La Ley de Demeter es un principio muy útil a la hora de estructurar nuestras clases para tener un bajo acoplamiento
y una alta cohesión. Es importante tener en cuenta este principio a la hora de diseñar nuestras clases para tener
un código más limpio y mantenible.
Sobre todo es muy importante analizar cada casuística ya que a veces la solución a una violación de la ley puede significar
que el dominio del sistema no está bien modelado y que hay que hacer cambios más profundos en la estructura del sistema.
¿Conocías la Ley de Demeter? ¿La aplicas en tu código?
También puedes pasarte por mi canal de YouTube para ver el vídeo sobre la Ley de Demeter:
¡Gracias por leer y espero que te haya gustado el artículo!
PD: Si tenéis cualquier duda podéis poneros en contacto conmigo enviando un DM a twitter.
0 comentarios