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 mas 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 mas acerca del funcionamiento de otros componentes o llegan a tener múltiples responsabilidades, son mencionados y usados 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 mas susceptibles a convertirse en clases dios . Hoy voy a hablar de las clases base que se convierten en clases dios.

La herencia mal entendida.

La herencia es una poderosa herramienta que permite extender o implementar comportamientos en un objeto. Es perfectamente valido 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 común, manejo de configuraciones, parseos, etc. . Usar herencia para compartir comportamientos no esta mal, lo malo es usar la herencia como pretexto para acceder a métodos sin relación alguna entre si.

Ejemplo del mundo real.

Estoy refactorizando un sistema legado viejo. La aplicación en cuestión esta escrita en ASP.NET 3.5, en esta tecnología todas las paginas 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 paginas que requieran de validar permisos solo tienen que heredar de WebClass que a su vez hereda de Page.

La tentación de usar 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 paginas podrán acceder a el. Bueno, si,  pero ¿a que coste?. Juntar responsabilidades y preocupaciones en los componentes hace costoso el mantenimiento y el Testing.

¿Como 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 mas sano que puedes hacer es duplicar el código en las clases hijas y remover las preocupaciones compartidas de la clase base.  Puedes pensar 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