La herencia entre clases, ¿a ti te deja dormir?

Una de las malas prácticas más comunes que solemos acusar los desarrolladores es el abusivo uso de la herencia entre clases. De hecho, yo mismo en mis primeros pasos en OO con Java en la universidad, asociaba erróneamente la OO a la herencia, es decir si no hay herencia no hay OO. El supuesto o teórico despiece que debe permitir la reutilización de código gracias a la flexibilidad de esta propiedad, lo confundía con descuartizarlo de tal forma que obtenía un rompecabezas lógico de clases inmanejable e ineficiente; eso sí, el diagrama estático en UML quedaba muy bien (en apariencia visual claro).


Hace relativamente poco, hablando con un ex profesor sobre el tema en cuestión, me comentó acerca de la existencia de un principio, el Principio de Sustitución de Liskov  (LSP), el cual permite confirmar la eficiencia (no eficacia) de una herencia entre clases. LSP recibe el nombre de Barbara Liskov quién lo presentó en un seminario de OO. En la herencia se establece la subclase como “es un” (“is a”) -especificación- de la clase base y Barbara argumentó que además de “ser un”, la subclase debía “comportarse como” . Andy Hunt y Dave Thomas (The pragmatic programmer) resumieron LSP como: “Las subclases deben ser usables a través de la interfaz de la clase base sin que el usuario tenga la necesidad de conocer la diferencia.”. (Más info)


Esta misma tarde, ha tenido lugar un Webcast de Bruno, en cual he participado como oyente. Más allá del Webcast en sí, el cual ha sido brillante como no podía esperar,  Bruno ha hablado sobre el mal uso que se hace –de forma genérica- de la herencia, la cual cosa me ha llamado la atención y me ha dado pie a que, posteriormente, una vez finalizado el Webcast, le hiciera una pregunta a acerca del uso de test unitarios basados  específicos para evaluar la eficienciade la herencia, ya sea por LSP u otros técnicas. La respuesta fue buena: destacó la abstracción de interfaces –efectivamente como una aproximación válida-  y de un principio que comparto absolutamente con él: el Principio del Sentido Común.


Ahora bien, ¿Qué factores influyen en el sentido “más común” del sentido común? La experiencia, la capacidad de abstracción, los conocimiento teóricos sobre el tema,,,,, Cuando oí hablar por primera vez del LSP instintivamente analicé código hecho por mí para verificar si se cumplía dicho principio y encontré una herencia en cuestión –estoy convencido que hay más- que no lo hizo, sin embargo, dicho código forma parte de una solución funcional, está en producción. Luego, ¿es incorrecto pese a que funciona? ¿Es eficaz, pero no eficiente? ¿Podría encontrarme problemas si decidiera o requiriera extender las clases? Si es así, ¿Debo tener en cuenta al pie de la letra el LSP u otros mecanismos cada vez que confeccione un diagrama estático de clases?


Ojo, no pretendo discutir el LSP, faltaría más. La herencia llevada de forma eficiente  reduce la complejidad al desarrollador al poderse centrar únicamente en los atributos genéricos evitando tener que entrar en detalles; LSP es un principio, no como axioma sino lógico, que determina el nivel de eficiencia de la herencia entre clases y, por consiguiente, es un principio válido. Me refiero más a la línea que marcan los principios y las doctrinas académicas y las necesidades y realidades actuales.


Probablemente en este punto entre en escena las técnicas de calidad y demás. Ahí no voy a entrar; en esta comunidad hay gente que sabe mejor que yo del tema; más bien me gustaría saber vuestra experiencia u opinión al respecto, anécdotas y situaciones paranormales más allá de los libros.


En fin, ahí se queda; el próximo sábado por la noche saldré, beberé, fumaré hasta perder el conocimiento; la herencia no me quitará el sueño 😉

4 comentarios en “La herencia entre clases, ¿a ti te deja dormir?”

  1. Al respecto de la herencia, es como muchos de lso conceptos en la programacion y aspectos de la vida, se pueden llevar a los excesos en algunos casos con consecuencias adversas.

    El mundo de Cocoa y objetive-c, la recomendacion sobre la herencia, es que hay que pensar dos veces en usar la herencia, en lugar de usar la composicion.

    Para realizar herencia es necesario entender a fondo la clase que va a servir como base, en cambio en la composicion unicamente con enterder la funcionalidad de la clase base que nos interesa es mas que suficiente.

    Saludos

  2. Mario: llevarlo a cabo dentro de los límites lógicos que marcan los extremos es precisamente el sentido común, sin embarg, éste, deja demasiado margen para posibles inconvenientes. Gracias por tu opinión,,,

    Miguel: Como dicen Los Chichos, Ni más, ni menos. Gracias. Por cierto, a las 6:39 estarías acostándote no??? 😉

  3. @andrechi
    Efectivamente… no la hay, por eso se apela al sentido común. 😉
    Lo que sin embargo sí que hay son síntomas de que estamos mal usando la herencia: p.ej. si una clase debe “quitar” funcionalidad de la clase base, o si un objeto necesita en algún momento cambiar de clase es porque estamos utilizando mal la herencia. Preveer (y por lo tanto) evitar estos casos es una de las tareas de un buen diseño.
    De todos modos tienes razón: denem echarse horas para evaluarlo… xD

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *