Funciones de Aptitud (Fitness Functions)

Cuando creamos una arquitectura, lo hacemos con un propósito, y muchas (o todas) las veces pensamos que la arquitectura que estamos ideando antes de iniciar el desarrollo es la que va a cumplir el propósito, que puede ser asegurarse del rendimiento, auditabilidad, escalabilidad, mantenibilidad, etc. (los llamados requerimientos no funciones)

El hecho es que muy pocas veces (o nunca) en realidad verificamos que el propósito de la arquitectura ideada se esté cumpliendo. Así mismo cuando nos encontramos desarrollando las aplicaciones y evolucionando la arquitectura (todas las arquitecturas evolucionan), no sabemos en realidad si el desarrollo de una solución está “respetando” o preservando la arquitectura o los principios de arquitectura, y nos damos cuenta cuando ya es muy tarde.

Parte de los conceptos de una arquitectura evolutiva son las funciones de aptitud (fitness functions) que en esencia, tratan de hacer verificables las características principales de arquitectura que guían una solución de manera constante e incremental.

Es así que cuando estamos diseñando una arquitectura nos preocupamos de que la solución sea escalable o mantenible (bonitas palabras), pero que significa que sea escalable, que tenga “buen” rendimiento o que sea mantenible, justamente es aquí donde entran las fitness functions, buscando hacer más objetivas estas características mediante mecanismos de verificación constantes.

Por ejemplo: si decimos que una arquitectura busca que la solución tenga “buen” rendimiento, entonces necesitamos crear una(s) función de aptitud que defina que significa “buen rendimiento”, creando un mecanismo de control que verifique en cada nueva versión de la aplicación que las operaciones o transacciones más importantes no tomen más de medio segundo en ser ejecutadas; esta función de aptitud puede ser ejecutada en el proceso de integración o entrega continua antes de liberar un nueva versión a producción.

Si buscamos que sea mantenible y entendemos que una de los aspectos para que la solución sea mantenible es crear una arquitectura en capas dónde buscamos que solo existan dependencias en una dirección (figura 1), entonces debemos crear una función de aptitud que verifique las dependencias entre paquetes sean solamente las que hemos definido (figura 2).

Captura de pantalla 2018-02-27 a la(s) 15.41.53

figura 1 –  Arquitectura en Capas

Captura de pantalla 2018-02-27 a la(s) 15.57.12

figura 2 – Función de aptitud que analiza dependencia entre capas

Dado que cuando estamos construyendo arquitecturas evolutivas buscamos soportar un cambio incremental y guiado a lo largo de múltiples dimensiones, es importante saber hacia donde estamos guiando el cambio y es aquí donde las funciones de aptitud juegan un papel principal, ya que son controles que nos permiten identificar si las características principales de arquitectura se están preservando al mismo tiempo que la arquitectura evoluciona, o en otras palabras: Las funciones de aptitud nos permiten identificar si la arquitectura está evolucionando hacia donde queremos que evolucione.

Capas de Anticorrupción

Ese momento de pánico cuando se decide cambiar la aplicación X de la que depende nuestro sistema.

Cuando construimos sistemas, la mayoría de las veces, estos dependen o necesitan de aplicaciones externas o de terceros. El momento en que una de esas aplicaciones externas necesita ser cambiada o se necesita hacer una actualización es cuando los problemas no cesan.

El mayor inconveniente muchas veces, no es que la nueva aplicación o versión no tenga las mismas funcionalidades que la anterior (de hecho muchas veces tiene más), el problema radica en que nuestro sistema está invadido de dependencias de esta aplicación externa; el problema es que nuestro dominio se ha visto corrompido por un dominio externo.

Screen Shot 2016-06-29 at 3.59.57 PM

Por ejemplo: Tenemos un sistema (cajas verdes) que maneja entre otras funcionalidades,  archivos y documentos, para lo cuál se ha decidido utilizar un repositorio de archivos como Alfresco (caja amarilla). Alfresco (o cualquier otra herramienta) provee librerías o API’s que son utilizadas por nuestro sistema para la integración. En este punto nuestro sistema/dominio tiene una dependencia de la herramienta externa a lo largo de varios componentes, por lo que decimos que nuestro dominio está corrompido ya que la herramienta externa (que puede ser un dominio diferente) esta “regada” por todo lado. El momento en que decidamos cambiar la herramienta Amarilla por una Roja se deberá buscar todas las dependencias en nuestro dominio y hacer el cambio hacia las nuevas dependencias.

Podemos evitar este problema introduciendo una Capa de Anticorrupción (término acuñado en el libro DDD) que nos permiten aislar las dependencias externas o de terceros, sean estas herramientas, sistemas, dominios diferentes, etc.

Screen Shot 2016-06-29 at 4.14.17 PM

La idea es construir una capa intermedia entre nuestro dominio y la dependencia externa, esta capa es la responsable de hacer las transformaciones en ambos sentidos, es decir; transformar los componentes de nuestro dominio en componentes que pueda entender la dependencia externa y viceversa. De esta forma logramos aislar esta dependencia en un solo punto, de tal modo que nuestro dominio (cajas verdes) esté enfocado en resolver el problema puntual para el que fue diseñado y que cualquier cambio en la dependencia externa no afecte mayormente al comportamiento de nuestro sistema.