Code Smells: God classes, herencia sobre composición.

Las clases dios son un mal conocido en los sistema legados. Todos los sistemas tienen componentes que son más usados que otros, estos tienen mayor visibilidad y son los candidatos perfectos para aplicar «cambios rápidos». Con el tiempo este tipo de objetos conocen más acerca del funcionamiento de otros componentes o llegan a tener múltiples responsabilidades, son mencionados y empleados en todas las partes del código, se vuelven omnipresentes y omniscientes (si modificas algo en una clase dios todo el sistema lo resiente).

Las clases utilitarias, las fachadas y las clases base son los objetos más susceptibles a convertirse en clases dios. Hoy voy a hablar de las clases base que se convierten en clases dios.

La herencia malentendida.

La herencia es una poderosa herramienta que permite extender o implementar comportamientos en un objeto. Es perfectamente válido compartir comportamientos comunes dentro de una familia de objetos a través de la herencia. Por ejemplo: Una función utilitaria que permita convertir un  dato a otro tipo, manejo de errores usual, manejo de configuraciones, parseos, etc. Usar herencia para compartir comportamientos no está mal, lo malo es usar la herencia como pretexto para acceder a métodos sin relación alguna entre sí.

Ejemplo del mundo real.

Estoy refactorizando un sistema legado viejo. La aplicación en cuestión está escrita en ASP.NET 3.5, en esta tecnología todas las páginas heredan de la clase Page. Los programadores anteriores decidieron seguir un esquema basado en la herencia para el manejo de valores de sesión y la verificación de permisos, hasta aquí todo bien, la solución suena razonable. Para reducir la reutilización de código se creo una clase llamada WebClass, todas las páginas que requieran de validar permisos solo tienen que heredar de WebClass que a su vez hereda de Page.

La tentación de emplear la herencia para «reutilizar código».

La clase WebClass se encuentra en todas partes, si pusieras un método o una propiedad ahí podrías, en teoría, escribir código reutilizable, ya que todas las demás páginas podrán acceder a él. Bueno, si,  pero ¿a qué coste?. Juntar responsabilidades y preocupaciones en los componentes hace costoso el mantenimiento y el Testing.

¿Cómo reparo este  smell?.

Lo ideal seria dividiendo las responsabilidades  e invirtiendo dependencias, en sistemas legados es una tarea difícil pensar en cambios arquitectónicos. Lo más sano que puedes hacer es duplicar el código en las clases hijas y remover las preocupaciones compartidas de la clase base.  Puedes suponer en definir un diseño que sea basado en la composición y luego en la herencia. También es posible que no necesites reconstruir el diseño y solo eliminando la clase dios reduzcas el coste de mantener el sistema. Todo esto depende del problema al que te estés enfrentando. No hay una solución única para este tipo de problema.

Autor imagen: Dennis Jarvis

Gustavo Sánchez
Últimas entradas de Gustavo Sánchez (ver todo)

Soy especialista en escribir software de calidad. Mediante el uso de marcos de trabajo, técnicas y automatización de procesos he podido reducir los costes operativos de los sistemas de la empresa. Sistemas confiables y adaptables producen clientes felices.