Composición sobre herencia en la construcción de tus entidades.

Construir las entidades de tu sistema requiere un cuidado especial. Las entidades deben de tener un gran valor conceptual, pero un poco valor funcional, entre menos lógica tengan son más fáciles de usar como base para construir la lógica de negocios de tus sistemas. En algún momento te vas a enfrentar a que hacer en las situaciones donde tengas que agregar cierta lógica  a la entidad, puedes escribir métodos privados o protegidos para encapsular el comportamiento. También, puedes emplear la clase base o una superclase-abstracta para depositar esa funcionalidad o  aplicar inyección de dependencias en el constructor o la invocación del método. Voy a tocar el caso en donde las entidades heredan de una clase.

Utilizar herencia para compartir funcionalidad.

Puedes elegir la herencia/encapsulación como método para construir la funcionalidad de la entidad. Tienes el beneficio de impedir que otros accedan a la lógica interna de la familia de objetos, pero vas a perder teniendo una dependencia interna y razones de fallo internas de las entidades, lo cual vuelve el objeto menos confiable. Por ejemplo: supongamos que debes construir un objeto que represente un usuario y que trate con el hash de una contraseña. El objeto en cuestión debe de ser capaz de comparar una cadena de entrada con el hash que almacena e indicar si coinciden.

¿Qué tiene de malo el ejemplo anterior?

Al tomar esta decisión de construcción estás haciendo que una entidad tenga dependencias, esto significa que cada servicio o regla de negocio que quiera emplear el concepto de usuario deberá también arrastrar las dependencias internas del objeto. Sin saber cómo es que funciona internamente, ni la posibilidad de modificarlo estás agregando razones de fallo y posibilidades de que surjan bugs. Y lo peor de todo, no existe la posibilidad de extender el comportamiento sin modificar el código base de la clase Usuario, ¿necesitas un algoritmo de hashing adicional?, entonces modifica la clase base con la posibilidad de agregar bugs a algo que ya funcionaba.

Necesitas agregar comportamiento a tu entidad, pero no quieres que se haga compleja, ¿qué puedes hacer?. La respuesta es:

Usar composición para construir funcionalidad.


Al trasladar la funcionalidad a otra parte mediante la inversión de dependencias puedes solucionar el problema de tener que lidiar con comportamientos específicos dentro de la entidad. No estoy en contra de emplear la herencia como herramienta para compartir funcionalidad, el problema es que sin un uso adecuado puede convertirse en un desastre. Puedes utilizar herencia para funcionalidad con poco valor, parseos, formateos, conversiones básicas.

Autor imagen: fdecomite

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.