¡Desacoplamiento, desacoplamiento, desacoplamiento!

Este texto es una traducción del artículo Découplage, découplage, découplage ! [fr] publicado el 4 de septiembre de 2017 por Julien Kirch, « arquitecto IT, desarrollador y geek, que pasa demasiado tiempo en Internet a mirar fotos de gatos ». Expresa unos conceptos claros sobre el desacoplamiento en los sistemas informáticos, que va más allá de la simple «modularización» y siempre implica costos adicionales a tomar en cuenta al momento de diseñar o modificar la arquitectura de un sistema.

Traducción el 8 de septiembre de 2017 por Sylvain Lesage y Natalia Antezana.

 

En informática nos encanta el desacoplamiento: que alegría sería tener pedazos de sistema evolucionando libremente cada uno por su lado.

Un sistema informático desacoplado casi es tan bueno como un sistema informático compuesto por gatitos, foto por Pieter Lanser en CC

Un sistema informático desacoplado, es casi tan bueno como un sistema informático hecho de gatitos, foto por Pieter Lanser en CC

Lamentablemente existen dos sombras en este panorama idílico:

  • el desacoplamiento presenta ventajas, pero también inconvenientes;
  • no existe un desacoplamiento, sino varios desacoplamientos, cada uno con sus características propias. Hablar de desacoplamiento sin precisar de cuál estamos tratando es tomar el riesgo de no entender el problema y entonces de tomar una mala decisión.

Un ejemplo simple de desacoplamiento

En la arquitectura de software, la programación estructurada es un ejemplo muy simple de desacoplamiento que apareció en los años 70. Revolucionaria en su época, consiste en encapsular su código en módulos— funciones o subrutinasen vez de usar unos GOTO [en].

El hecho de encapsular código en subrutinas expuestas mediante unas API formalizadas— en vez de una masa de código sin forma —permitió mejorar la legibilidad de los programas y la calidad de los desarrollos.

Este ejemplo integra las tres características que encontraremos en los casos de desacoplamiento a nivel de un sistema informático:

  • una necesidad: mejorar la legibilidad y la calidad el código;
  • un medio: nuevas sintaxis específicas;
  • un inconveniente: una gran lentitud con las computadoras y compiladores de esa época, a tal punto que usar funciones fue una práctica controvertida durante un tiempo.

Los tres tipos de desacoplamiento de sistema informático

A nivel de un sistema informático existen tres grandes tipos de desacoplamiento:

Los tres tipos de desacoplamiento que nos interesan

Los tres tipos de desacoplamiento que nos interesan

  • el desacoplamiento de formato: cuando la ejecución de una funcionalidad pasa por la utilización de un contrato de interfaz estable;
  • el desacoplamiento de temporalidad: cuando la ejecución de una funcionalidad se hace más tarde de manera asíncrona;
  • el desacoplamiento de ubicación: cuando la ejecución de una funcionalidad se hace en otro lugar.

Estos desacoplamientos son diferentes, aunque presenten zonas de recubrimiento.

El desacoplamiento de formato

Es el más común en las charlas sobre desacoplamiento en un sistema informático. Es fundamental en una organización de un cierto tamaño, porque responde a dos grandes necesidades:

  • tener el control sobre las consecuencias de una modificación de una parte del sistema;
  • permitir a diferentes equipos trabajar de manera independiente, limitando los esfuerzos de coordinación.

El medio consiste en definir que ciertos contratos de exposición son estables y utilizables desde el exterior; de manera opuesta a los contratos «de uso interno» que no cubren estas garantías.

Los inconvenientes son el costo adicional creado por el esfuerzo de formalización, y el riesgo generado si este desacoplamiento está mal hecho: en efecto, el prerrequisito para realizar este desacoplamiento es que las funcionalidades a exponer sean maduras y evolucionen poco, o de una manera que no implique hacer evolucionar el formato de exposición. Si las funcionalidades a exponer no son del todo maduras, se toma el riesgo de exponer una interfaz defectuosa [en]. En este caso, el costo adicional de implementación y mantenimiento del formato podrá ser más importante que el beneficio que trae, porque cada cambio implica costos y/o demoras: comunicación, pruebas de integración, gestión de compatibilidad…

La utilización de buenas prácticas y de herramientas como el DDD [fr] [Ndt: Diseño guiado por el dominio] puede facilitar la definición de interfaces, pero lo más difícil para exponer API estables es conocer perfectamente la lógica de negocio.

Los beneficios de un desacoplamiento de formato se hacen sentir también entre submódulos de una misma aplicación porque vuelve el código más legible y limita las necesidades de refactorización al momento de las evoluciones. Es una de las bases de la reutilización.

Acuérdese sin embargo que un desacoplamiento de formato casi nunca es total, sino que a lo mejor se trata de un bajo acoplamiento: con el tiempo todos los servicios evolucionan, y por lo tanto sus contratos también.

El desacoplamiento de ubicación

Es una de las bases de la informática distribuida: responde a la necesidad de poder acceder a una funcionalidad distante sin tener que conocer precisamente el o los dispositivo(s) que la proveen. Permite remplazar, desplazar, añadir o suprimir las máquinas que entregan esta funcionalidad, de manera transparente para cada consulta.

El medio es la implementación de una capa de indirección [en]   entre los sistemas como un DNS o unos proxys: en vez de acceder a un sistema directamente por su nombre, se usa un intermediario.

Eso cubre los diferentes tipos de servicio distribuido como CORBA, SOAP o REST, pero también las bases de datos no locales y los sistemas de archivos distantes.

Un desacoplamiento de ubicación sin desacoplamiento de formato puede ser útil al interior de un mismo sistema, porque permite desplegar de manera separada diferentes componentes y poder gestionar la resiliencia [en]. Es el caso por ejemplo de las bases de datos donde una librería cliente expone una API para realizar consultas al servidor.

El inconveniente del desacoplamiento de ubicación es que añade:

  • nuevos tipos de errores e incertidumbres;
  • complejidad para supervisar y corregir los tratamientos;
  • latencia para la serialización / deserialización y las transferencias en la red.

Así que, en caso de necesitar un desacoplamiento de formato y no de ubicación, trabajar sobre módulos dentro de una misma aplicación es una estrategia absolutamente válida. Sin embargo, el caso más comunmente escuchado cuando se habla de desacoplamiento corresponde a un desacoplamiento de ubicación y de formato. Gracias a él, los equipos pueden trabajar y desplegar sus componentes y al mismo tiempo limitar las dependencias.

El error más común sobre el desacoplamiento consiste en pensar que un desacoplamiento de ubicación implica necesariamente un desacoplamiento de formato. Es cierto que exponer unas funcionalidades a través de servicios obliga a definir un contrato de servicio, o sea una interfaz formal, pero nada garantiza que este contrato de servicio permita por si mismo un real desacoplamiento.
Es el error clásico de los sistemas de información de servicios implementados sin gobernanza. Por ejemplo, podemos pensar que exponer unas funcionalidades en REST y proveer una documentación Swagger [en] permite un desacoplamiento de formato, porque entonces es posible llamarlas con conocimientos mínimos y pocas interacciones con las personas a cargo. Pero si este contrato de interfaz evoluciona cada semana, tener un contrato de servicio formalizado no impedirá que cada vez haya que modificar el código.

El desacoplamiento de temporalidad

Corresponde a ejecutar un tratamiento más tarde de manera asíncrona. Se hace generalmente por el medio de una cola de mensajes [en], de un envío de archivo, o de una base de datos.

Permite responder a dos necesidades:

  • no bloquear la aplicación que lanzó la solicitud, postergando una parte de los tratamientos;
  • gestionar más fácilmente los picos de carga, por lo menos entre tanto la herramienta a cargo de gestionar las solicitudes de ejecución no esté sumergida.

Hay tres mayores inconvenientes:

  • hay que tener certeza de no perder solicitudes de tratamiento, ni duplicarlas (o asegurarse que si ocurre, no tenga consecuencias nefastas);
  • complica la gestión de los errores y de la coherencia de datos;
  • complica la supervisión del sistema, requiriendo generalmente la implementación de herramientas de monitoreo de flujo [fr].

Un desacoplamiento de temporalidad sin desacoplamiento de formato complica las subidas de versión. En efecto, obliga a gestionar la compatibilidad entre versiones o esperar que todas las solicitudes hayan sido tratadas antes de actualizar el sistema. Sin embargo, cuando la asincronía [en] está utilizada dentro de una misma aplicación, esta metodología puede ser adecuada porque evita tener que preocuparse de la gestión de compatibilidad.

La implementación de un desacoplamiento de temporalidad en la mayoría de los casos pasa por la utilización de una herramienta externa a la aplicación (cola de mensajes, base de datos…). Según su implementación y su configuración, esta herramienta puede proveer una forma «natural» de desacoplamiento de ubicación. Si bien en este caso es fácil su implementación desde un punto de vista de la infraestructura, no significa que sea gratis, porque el costo adicional en complejidad generada por los nuevos comportamientos a tomar en cuenta, es real.

Para concluir

A través de los tres tipos de desacoplamiento y de sus intersecciones, hemos visto que desacoplar no es un fin en sí, sino un medio para responder a ciertas necesidades y este medio también tiene sus inconvenientes, en particular efectos colaterales en el lugar donde se realiza el desacoplamiento. También hemos notado que acumular los desacoplamientos permite acumular las ventajas pero también los inconvenientes.

Lo más difícil, que no se puede resumir en un artículo, es determinar cómo y en qué lugar se debe desacoplar en función de las necesidades a satisfacer: ya son más de 30 años [en] que la cuestión está abierta. Si añadir una cierta cantidad de desacoplamiento es necesario en los sistemas grandes, hacerlo mal puede también llevar al desastre.

P.D.: me vino la idea de este artículo luego de haber leído este texto [en] que hace un muy buen análisis de la utilización de middleware de mensaje para gestionar tareas asíncronas.

Deja un comentario

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