Code smells: ¿Que es una data class?

Un code smell común  es el denominado: Data Class (DC). Una DC es un objeto que solo sirve de transporte de datos, únicamente contiene campos públicos o getters y setters. Esto en  principio no es malo. Primero hay que aclarar el siguiente punto: existen dos tipos de unidades conceptuales en la programación orientada a objetos: la estructura de datos y la clase. Cada una de estas tiene un uso particular.

¿Cual es la diferencia entre una clase y una estructura de datos?.

Una estructura de datos (no confundir con structs), representa un concepto, tiene poca o nula funcionalidad mas allá de servir de transporte o agrupación de datos. Las clases también contienen estados  e implementan o declaran funcionalidad. Las clases en la solución inician siendo estructuras de datos y conforme pasa el tiempo pueden ser promovidas a ser clase. Esto depende del diseño de la aplicación.

Ejemplo de una estructura de datos:

Ejemplo de una clase:

En este punto te preguntaras,  si una estructura de datos solo contiene propiedades, ¿entonces ya es una DC?, la respuesta es un rotundo NO. Una DC  viola el principio de única responsabilidad y agrega dependencias innecesarias, esto es lo que la convierte en un anti-patrón. Tomemos el ejemplo de la clase Credenciales para ver cuando surge una DC.

¿Como se ve una Data Class?.

Supongamos que un programador perezoso en la empresa decidió reciclar la clase Credenciales para codificar un requerimiento. Al ser una clase común y conocida es mas fácil usarla por todo el sistema. Nuestro programador en cuestión implemento el registro de usuarios y direcciones, para ello agrego propiedades adicionales a la clase Credenciales.

Como fue codificado este requerimiento agrega dependencias y por lo tanto razones de fallo. Si se cambia algo en la clase Credenciales hay 3 posibles afectaciones en lugar de una. Sumado a que todos los componentes saben demasiado acerca de otros. Para finalizar la clase Credenciales dejo de ser honesta, no solo representa las credenciales de acceso sino mucho mas. Este tipo de clases es común en los sistemas legados o viejos. Es un caso clásico de alta dependencia.

Para este caso hay dos soluciones, crear las estructuras de datos Domicilio y Usuario, luego hacer los ajustes en las clases ProveedorUsuarios y ProveedorDomicilio. O también se puede invertir la dependencia mediante el uso de interfaces.

¿Como remover la DC implementando el principio de única responsabilidad?.

La solución mas aplicada para tratar con una DC es partir esta clase en elementos individuales, al tener elementos que funcionan de forma separada se rompe la dependencia:

¿Como remover la DC implementando inversión de dependencias?.

En un mundo ideal las DC no deberían de existir. En el momento que se encuentra uno de estos monstruitos se debería remover lo antes posible del código base. Desgraciadamente esto no es posible siempre, sobre todo en sistemas viejos, legados o altamente acoplados. Existen técnicas para aislar estos objetos y poder romper este anti-patrón. La inversión de dependencias permite trabajar con un objeto grande como una  DC y limitar su impacto en otros componentes, te muestro el ejemplo:

Autor imagen: ryancr