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 mas 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 usar 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.

Usar 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.

¿Que tiene de malo el ejemplo anterior?

Al tomar esta decisión de construcción estas haciendo que una entidad tenga dependencias, esto significa que cada servicio o regla de negocio que quiera utilizar el concepto de usuario deberá también arrastrar las dependencias internas del objeto. Sin saber como es que funciona internamente, ni la posibilidad de modificarlo estas 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, ¿que 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 usar la herencia como herramienta para compartir funcionalidad, el problema es que sin un uso adecuado puede convertirse en un desastre. Puedes usar herencia para funcionalidad con poco valor , parseos, formateos, conversiones básicas.

Autor imagen: fdecomite

Gustavo Sánchez