Presentamos los cursos de CodelyTV: ¡CodelyTV Pro! 🚀

¡Subscríbete ahora y aprovecha la oferta de lanzamiento al 50%!

Por qué NO usar getters y setters | Tell don’t ask

¿Usas getters y setters? ¿Te suenan los modelos de dominio anémicos? ¿El principio Tell don’t ask? ¡En este vídeo aprenderemos más acerca de estos conceptos!

Ya hemos trabajado un poco la parte de la capa de aplicación mediante el screencast sobre el principio de responsabilidad única, y la relación con la capa de infraestructura mediante el screencast sobre el principio de inversión de dependencias. En este vídeo nos centraremos en la capa de nuestro dominio, concretamente, los modelos de dominio.

Índice del vídeo

  • 0:19 Pregunta: En PHP se accede a atributos de clase públicos, ¿uso getters y setters?
  • 1:17 Principio de programación aplicable a todo lenguaje
  • 2:00 Modelo User con atributos de clase públicos
  • 3:19 Diferencia entre Data Transfer Object (DTO) y modelo de dominio. Qué es un modelo de domino anémico
  • 4:14 Qué problemas tiene usar atributos de clase públicos
  • 4:50 Modelo User como array asociativo/hashmap
  • 6:00 Qué problemas tiene usar arrays asociativos para el modelado de dominio
  • 6:50 Modelo User con atributos de clase privados, getters y setters (modelo anémico)
  • 7:17 Beneficios de usar getters y setters
  • 8:00 Por qué NO usar getters y setters
  • 9:12 Modelo de dominio User con comportamiento
  • 10:47 Qué beneficios tiene usar modelos de dominio ricos (con comportamiento)
  • 13:09 Conclusión: Ni atributos de clase públicos, ni getters y setters. Lo ideal: Lógica de negocio donde corresponda (alta cohesión)

Vídeo

Material relacionado

  • Tell don’t ask: Artículo de Martin Fowler acerca del principio Tell don’t ask
  • Tell, Don’t Ask (thoughtbot): Ejemplos de violaciones del principio Tell don’t ask en Ruby
  • Data Transfer Object: Artículo de Martin Fowler sobre el patrón de diseño DTO
  • Anemic Domain Model: Artículo también de Martin Fowler acerca del anti-patrón de modelos de dominio anémicos
SHOWHIDE Comments (5)
  1. No explicas “porque no usar getters”.

    Según veo en tu código en lugar de getEmail(), usas el método email(). ¿Que mal hay en usar el primer nombre, o que ventajas de usar el último?.

    1. ¡Buenas Pablo!

      Sobre lo de que no explico por qué no usar getters, creo que es simplemente una cuestión idiomática. Es decir, con el título “Por qué NO usar getters y setters”, simplemente intento resumir lo que sería la manera de trabajar que se puede ver en el vídeo. Básicamente: obtener los datos de nuestros modelos de dominio (getters), ejecutar una determinada lógica fuera de estos modelos, y establecerle los valores ya modificados a estos modelos (setters).
      Con lo cuál, no es que no se deban usar ni getters ni setters, si no que más bien se trata de intentar encapsular la lógica de negocio en nuestros modelos de dominio siempre que sea posible y que estos no sean meros DTOs. Es decir, aplicar el principio Tell don’t ask para evitar modelos de dominio anémicos.

      Sobre lo del no usar el prefijo get, es una mera convención y no veo nada malo en algo como getEmail(). Decidimos esto ya que consideramos que ya se entendía que, al hacer un $user->email(), se está obteniendo el email del usuario y no es necesario el prefijo get. Pero no va más allá de eso. Se comentaba esto por encima en el vídeo de Generación automática de código con IntelliJ y PhpStorm: http://codely.tv/screencasts/generacion-codigo-intellij-phpstorm/

      Un saludo y merci por el comentario 🙂

  2. Buenas Javier!

    Creo que deberías contar primero cual es tus especificaciones de modelo. Decir que trabajar con getters y setters es una mala praxis no tiene ningún sentido. En este caso, si asumes que email, birthday y password son obligatorios y no pueden cambiar, pues esta clase estará correctamente diseñada post refactoring (ValueObject en toda regla). En otro caso donde birthday no fuera obligatorio para la existencia de User, pues deberíamos tenerlo en el setter (para añadirlo, quitarlo, etc…).

    Por otro lado, es obvio que si nuestro sistema necesita el birthday a pelo, por alguna razón, ya sea para poder sacarlo en un formulario, pues deberemos tener un getter, no?

    Respecto lo de modelo anémico o rico, tiene que ver mucho con la arquitectura de cada software. Hay gente que prefiere tener toda su lógica de negocio en una capa de servicios y hay gente que la prefiere dentro de sus entidades. Todo tiene que ver con asignar responsabilidades y roles, y como en todo, hay distintos pensamientos y corrientes.

    Generalizar no es bueno, porque mucha gente verá estos videos y se creerán que al poner un setter lo están haciendo mal, y no es así. Es importante darle a las personas herramientas para decidir según su caso de uso, ya que de ello depende muchas de las cosas que harán.

    Seguiré los videos con mucho interés.
    Muchos ánimos 🙂

    Saludos!

    1. Te doy toda la razón señor 🙂

      Como le decía a Pablo en el comentario anterior del post, en el vídeo entro más en detalle en este concepto y básicamente “no es que no se deban usar ni getters ni setters, si no que más bien se trata de intentar encapsular la lógica de negocio en nuestros modelos de dominio siempre que sea posible y que estos no sean meros DTOs. Es decir, aplicar el principio Tell don’t ask para evitar modelos de dominio anémicos.”.

      Esto nos lleva a la segunda cuestión que planteas, si realmente tiene sentido que nuestros modelos de dominio sean ricos por norma y no mover esta lógica a servicios asumiendo la anemia como algo que no es nocivo. Nuevamente estoy completamente de acuerdo contigo. Dependiendo del contexto y el caso particular, nos puede interesar llevarnos esa lógica fuera de los modelos. En la conclusión final del vídeo debería haber hecho más énfasis en que esto no es algo que se deba aplicar en todos los escenarios. No obstante, lo que me suelo encontrar de forma más común, son modelos de dominio como DTOs en contextos donde no está justificado. Con lo cuál, partí de esa base sin tener en cuenta lo que comentas. :-/

      Recuerdo una charla tuya sobre las decisiones de diseño que habíais tomado en Elcodi donde hablabas al respecto de la visibilidad de los atributos de clase. Como comentabas, nuevamente esto es algo que, marcado por el hecho de ser un proyecto Open Source, varía con respecto lo que sería más común. Es decir, en ese contexto tiene sentido que muchos de los atributos de clase sean protected y no private, como sí haríamos en un proyecto propio. Coincido en que es importante destacar este tipo de cosas, así que merci por el comentario y lo tendré más en cuenta para los siguientes vídeos 😀

      ¡Saludos!

Leave a Reply

Your email address will not be published.

¡Presentamos #CodelyTvPro! 🚀

¡Subscríbete ahora y aprovecha la oferta de lanzamiento al 50%!