Cohesión y el principio de responsabilidad única

Imaginemos que nuestro siempre creativo usuario nos solicita un proceso que genere cierto reporte Excel con información de base de datos y se lo coloquemos en un servidor FTP para que lo pueda descargar luego. Dado que -para variar- quiere el reporte para ayer, construimos la siguiente solución apresurada:

Diseño improvisado
Terminamos, el usuario lo prueba, mira que es bueno y nos felicita. 

Pasan unos días y el mismo usuario nos pide una aplicación para que pueda colocar algunos documentos PDF en el mismo  servidor FTP. ¿Por qué no utilizamos a nuestra clase AdministradorDeReportes junto a su método enviarArchivoFTP()? Podríamos hacerlo, pero nuestra clase para poder ser compilada depende también de POI y de JDBC lo que le daría una carga extra de 5 megas a nuestro sencilla aplicación para PDF's. Esto pone en evidencia que nuestro diseño original tiene algunos problemitas.

La cuestión es que nuestra clase AdministradorDeReportes tiene la responsabilidad de conectarse a base de datos, de generar un archivo Excel con esta data y de colocar el archivo en el servidor FTP; y si uno quiere reutilizar este componente pues no le queda otra que adquirir el paquete completo de responsabilidades que esta clase posee. ¿Y si queremos otra clase que genere el mismo reporte en HTML en un browser? Sería bastante conveniente utilizar el método obtenerInformacionBD ()de AdministradorDeReportes, pero una vez más tenemos el problema que esta clase tiene dependencias que no necesitamos (ni el API para conexión a FTP ni la generación de Excel). Dado que es obvio que nuestro diseño inicial tiene problemas, corregimos y planteamos lo siguiente:

Después de recapacitar, planteamos esto
Con esta nueva solución, la aplicación para transferir archivos PDF solamente debería utilizar la clase ClienteFTP sin la sobrecarga del resto de API's que no necesita; y si se requiere el reporte HTML que planteábamos sólo dependeríamos de la clase ExtractorDeDatos. Este diseño tiene la peculiaridad que nuestras clases están bastante especializadas y tienen una única responsabilidad específica: Por ejemplo, la clase ClienteFTP se ocupa de la conexión con el servidor FTP y nada más. Es esta especialización lo que nos da bastante flexibilidad para la reutilización, que es lo que trata de decirnos Robert C. Martin con su Principio de Responsabilidad Única:

“Nunca debe de haber más de una razón para que una clase sea modificada”

Si vemos nuestro diseño inicial, la clase AdministradorDeReportes debería modificarse si es que se requieren datos extra en el reporte. Esta clase también debería modificarse si quieren que el reporte Excel tenga otros colores. Y si quisiéramos optimizar la conexión con el servidor FTP nuestra clase AdministradorDeReportes también debería pasar por mantenimiento, por lo que tenemos un ejemplo bastante claro de como violentar este principio. Ahora, en nuestra versión mejorada del diseño hemos transferido estas responsabilidades a las clases ExtractorDeDatos, ClienteFTP y ReporteadorExcel; de modo que cada cambio que mencionábamos  ahora impacta solamente en una clase de nuestro programa.

5 comments

Muy interesante está información sigue así.

Reply

Excelente información!

muy útil y aplicable a la vida cotidiana

Reply

Hola, tienes un buen e interesante blog, felicidades. Me gustaría poder enlazarlo para que quienes visiten mi blog, puedan informarse con los articulos que tiene. Por favor, si estás interesado contáctame a manganimemaster@gmail.com Saludos cordiales.
s

Reply

Muy bueno el articulo, felicidades.

Reply

Hola Marcos, gracias por el comentario. Veremos si en estos días podemos sacar artículos extra xD.

Saludos!

Reply

Publicar un comentario