Ley de Demeter: Habla sólo con tus amigos
La Ley de Demeter, es una de esas prácticas indispensables que debe conocer y aplicar todo desarrollador de software (al menos así pienso yo).
Es una regla que nos orienta a reducir el acoplamiento de los componentes/clases/módulos de nuestros sistemas evitando que un objeto A que conoce a B, un objeto B conoce a C y A NO conoce a C entonces A NO debe poder manipular ni enviarme mensajes a C por medio de B, si lo hace incumple la Ley de Demeter, en palabras mas sencillas, significa que un método m de una clase o solo debería poder enviarle mensajes a estos tipos de objetos:
- el propio objeto o
- objetos provenientes de los parametros que recibe el metodo m
- de cualquier objeto que instancie m
- de cualquier atributo de o
Esto evita llamadas del tipo a().b().c().d() que claramente indican un problema en nuestro código.
Buscando como ejemplificar encontré el ejemplo del chico-diariero (paperBoy, parece ser un ejemplo clásico de esta ley ). El ejemplo se basa en la relación entre el Diariero y el Cliente del diario en el momento en que se quiere cobrar tan solo un diario entregado.
Veamos un ejemplo que viola la Ley de Demeter:
(aclaro que estos códigos los hice on-the-fly, no estan probados y pueden generar errores, solo son de ejemplo)
class Diariero { static protected $costoDiario = 5; public function cobrarDiario(Cliente $cliente) { return $cliente->getBilletera()->extraer(static::$c ostoDiario); } } class Cliente { protected $billetera; public function __construct() { $this->billetera = new Billetera(100); } public function getBilletera() { return $this->billetera; } }
Evidentemente la clase Diariero termina manipulando la clase Billetera sin necesidad alguna.
Un ejemplo correcto seria:
class Diariero { static protected $costoDiario = 5; public function cobrarDiario(Cliente $cliente) { return $cliente->cobrar(static::$costoDiario); } } class Cliente { protected $billetera; public function __construct($billetera) { $this->billetera = new Billetera(100); } public function cobrar($monto) { return $this->billetera()->extraer($monto); } }
En este ejemplo vemos que el método cobrar diario envía un mensaje a un objeto pasado por parámetro y el método cobrar invoca a un objeto de un atributo de su clase, ambos cumplen con la Ley de Demeter.
Desventajas
- a veces requiere escribir muchos métodos pequeños de “envoltura” (llamados a veces Demeter Transmogrifiers) para poder propagar llamadas del método a los componentes. Martin Fowler dice que sería mas correcto llamar a esta regla La sugestión de Demeter, ya que no es absoluta.
Para mas información pueden visitar:
- la web de la Ley de Demeter
- Ley de Demeter
- Introducing Demeter and its Laws
- POO – Ejemplos de la ley de Demeter
- La Ley de Demeter: definición y ejemplos
- Ley de Demeter, o del buen estilo: elegancia en POO
Fuente: mostofreddy
MostofreddY
Registro automático