Ir al contenido principal

Reintegrando el Marco de Trabajo

La migración siempre es difícil. Cuando queremos pasar de un sistema a otro nos encontramos con dificultades porque nuestro sistema depende de características especificas de un sistema subyacente...

Sería más fácil, si pudiéramos escribir un sistema que funcione sobre otro sistema... pero no depende este.


Considerando que hay sistemas externos - sea la base de datos, correo electrónico, etc... - y no queremos depender de ninguno de ellos. Tiene sentido crear capas que nos aíslen de estos sistemas.

Lo que nos queda, después de quitar el código que interactua con otros sistemas es "la lógica del negocio" (nombre con el que no estoy de acuerdo, porque ¿quién ha dicho que el software es para un negocio? y incluso si lo es, ¿quién dice que la lógica del software coincide con la del negocio? de hecho ¿quién dice que el software tiene lógica? - considere, por ejemplo, que el software es un vídeo juego). Así que le voy a dar otro nombre: Espacio de Dominio.

Nota: El espacio de dominio corresponde al Controlador (recordar que el Controlador no recibe la entrada, la entrada la recibe el Enrutador) y las Entidades del Modelo (no el acceso a datos, ni el ORM, sino las entidades).

En este Espacio de Dominio, queremos implementar el comportamiento del sistema (sea lo que sea), en términos independientes de las tecnologías subyacentes.


Ah, pero nos estamos olvidando del Marco de Trabajo que estamos usando para programar. Ese también es un sistema externo. En el momento en que hacemos una dependencia fuerte (por ejemplo, herencia), estamos limitando nuestras posibilidades de migrar a otro Marco de Trabajo.

Hay dos razones para hacer esta dependencia:

  • El Marco de Trabajo nos ofrece librerías útiles para el desarrollo.
  • Necesitamos indicar al Marco de Trabajo que partes de nuestro código llamar.

Para indicar que partes del código llamar... utilizamos herencia, o marcamos los archivos con comentarios u otros atributos, o los ponemos en carpetas con nombres específicos. Parece imposible lograr esto de una forma que el código y su organización sea agnóstica al Marco de Trabajo... pero ¡no es así! - lo que debemos hacer es crear otro componente, el cual depende de nuestro Espacio de Dominio y del Marco de Trabajo. Llamaré a este componente "Lanzador" (por razones que serán evidentes en el futuro).

El Lanzador utiliza su dependencia al Marco de Trabajo para indicarle que debe llamar el código en nuestro Espacio de Dominio.

En cuento a las librerías, debemos - siempre que tenga sentido - crear adaptadores, los cuales el lanzador debe inyectar, de forma que el Espacio de Dominio los reciba como parámetros.

Hecho correctamente, y el dominio no tendrá ninguna referencia, ni ninguna pista que es para un determinado Marco de Trabajo (excepto, tal vez, el lenguaje en que está escrito).

Ahora, el Espacio de Dominio necesita llamar sistemas externos. Para esto, le vamos a ofrecer servicios. Estos también deberán ser inyectados.

Necesitaremos algún tipo de configuración para saber que cosas inyectar... con esto, el lanzador tiene cuatro razones de cambio:

  • El Marco de Trabajo
  • El Espacio de Dominio
  • Los Servicios
  • La Configuración

En mi opinión, se debe tratar la configuración como un servicio. Habrá un componente dedicado a encontrar los servicios, y habrá un adaptador para interactuar con los servicios según su tipo... por ejemplo, algunos pueden estar escritos en un lenguaje interpretador, otros son librerías que hay que cargar según su sistema (eh: .jar, .dll, etc...) y otros podrían ser archivos de configuración (.json, .xml, etc...), y para cada caso habrá un adaptador que se encargue de cargarlo y extraer el resultado. ¿Qué unos tienen funciones y otros tienen datos? - un servicio siempre debe ser una función. Es trabajo del adaptador identificar los servicios y exponerlos. Para una librería, pueden haber varios servicios, para un .json podemos tener servicios para leerlo y escribirlo.

Ok, pero... ¿cómo escribir estos servicios de forma agnóstica al lanzador, para que el lanzador sepa que parte del código llamar? ¿Acaso ese no era el problema que el Lanzador estaba tratando de solucionar (pero con el Marco de Trabajo y el Espacio de Dominio)? - La respuesta que hay configuración que nos dice que cargar. Por tanto, si tenemos problemas para indicar que parte de una librería se puede llamar, lo que necesitamos es un archivo de manifiesto que nos diga que parte llamar, y un adaptador de servicio que maneje estos manifiestos.


Este articulo toma inspiración de la "The Clean Architecture" por alias "Uncle Bob".

Comentarios