Ley de Demeter

Ley de Demeter

¿Cirujanos o Desarrolladores?

Nov 10, 2022·

3 min read

Extraña pregunta... ¿Somos cirujanos o programadores? Ultimamente mi esposa está disfrutando sus ratos libres mirando Grey's Anatomy donde están estos personajes que les encanta cortar y abrir gente, van capa por capa abriendo tejidos hasta que llegan donde deben y obtienen la información necesaria para reparar lo malo. ¿Qué tiene que ver esto con un programador? Bueno, lo mismo me pregunto yo...

El problema

En la programación orientada a objetos es normal encontrar un objeto que contiene a otros y esos otros, a otros más. Muchas veces terminamos con códigos como este:

BookId bookId = customer.getHeader().getBriefcase().getBook().getId();

Nos llenamos de getters y terminamos con un problema que ya revisamos en el artículo sobre Train Wreck. Nos convertimos en cirujanos abriendo capa tras capa de un objeto hasta llegar a donde necesitamos.

El problema es el alto nivel de acoplamiento con el que terminamos, ya que la estructura de los objetos están relacionadas y un cambio en uno de ellos puede repercutir en los demás. Violamos el Open/Close Principle.

Ley de Demeter

Si alguna vez quieres sonar cool... apréndete lo siguiente: Teniendo una función f de una clase C, esa función sólo llama a funciones de:

  • C
  • Un objecto creado por f
  • Un objeto pasado como argumento a f
  • Un objeto en una variable de instancia de C

El objetivo es disminuir el acoplamiento entre las clases. Si una clase debe meterse dentro de otra, hurgando en sus entrañas siendo que no es una "conocida" de ella, está mal.

Es como aceptar caramelos de un extraño... o que la cajera de una tienda entre a tu billetera a sacar el dinero que necesita para cancelar tú compra.

Si intento traducir la Ley de Demeter sería algo como:

  • Yo (C) sólo puedo realizar una acción (f) (si quisiera pagar un producto):
    • sobre mi mismo (C) (buscar la billetera en mis bolsillos),
    • sobre el resultado de mi acción principal (f), (el vuelto de lo que he pagado)
    • sobre una billetera que se pasan a mi acción (f) pagar, (como la billetera de mi esposa?)
    • sobre una billetera que llevo en el bolsillo. (porque traía la billetera conmigo [instanciada])

No debemos ser muy estrictos con esta ley. Martin Fowler prefiere llamarla en su opinión personal como La sugestión de Demeter.

Alternativas para no violar este principio

Tener una arquitectura sólida en tu proyecto

Ocupar tiempo en planificar una buena arquitectura y diseño es la mejor inversión en cuanto a desarrollo de software se refiere. Que cada capa se pueda comunicar con interfaces claras y con buenas abstracciones disminuirán las violaciones a esta ley.

Principio Tell don't ask

Este principio también lo mencionamos en el artículo sobre Train Wreck. Trata principalmente sobre la comunicación y el traspaso de información de un objeto a otro. Donde el objeto que consulta no debiera recibir los datos para ser procesados, sino que debiera recibir la información ya procesada y lista para ser usada.

Volvemos al ejemplo de la billetera: ¿Debo permitir que una cajera de un mercado saque el dinero de mi billetera para cancelar mi compra? ó ¿Debo yo entregar el monto solicitado para ejecutar el pago?

Domain Driven Design

Los cambios e incrementos empujados por el dominio son la mejor opción. El negocio cambia más lento que el software, eso puede ser una ventaja cuando las características de nuestro sistema surgen por ese mismo negocio. De esta forma podemos tener sistemas que no cambiarán en su lógica por mucho tiempo. Además, DDD nos da muchas herramientas que nos ayudan a modelar nuestro software.

Conclusiones

En fácil violar la Ley de Demeter en la programación Orientada a Objetos. Tendemos a modelar nuestras soluciones sin pensar mucho en las responsabilidades de cada componente y en los alcances de ellos. Invertir tiempo en diseño y planificación nos puede ahorrar muchos malos olores de código, y también nos permitirá tener mejores abstracciones y un código más robusto, mantenible y escalable en el tiempo.

Gracias por la lectura!