Introducing Bounded Contexts in a monolithic application - Robert Baelde - DDD Europe 2022

Introducing Bounded Contexts in a monolithic application - Robert Baelde - DDD Europe 2022

Introducción al Contexto de Bounded en Aplicaciones Monolíticas

La complejidad en proyectos monolíticos

  • El presentador introduce el tema de cómo introducir contexto de bounded en una aplicación monolítica, comenzando desde un proyecto nuevo y la necesidad de entregar valor rápidamente a los clientes.
  • A medida que se añaden más características y miembros al equipo, la productividad comienza a disminuir debido a la creciente complejidad del proyecto.
  • La complejidad puede llevar a una experiencia negativa para los desarrolladores, quienes pueden sentirse abrumados por el modelo mental necesario para entender toda la aplicación.
  • Se menciona que es difícil predecir el impacto de los cambios, lo que complica las sesiones de planificación y puede resultar en estimaciones muy variables.
  • La incorporación de nuevos ingenieros se vuelve complicada debido a la falta de claridad sobre cómo está estructurada la aplicación.

Problemas derivados del aumento de complejidad

  • Existe una falta de claridad sobre quién tiene conocimiento experto sobre diferentes aspectos del sistema, dificultando la asignación de responsabilidades.
  • Los desarrolladores comienzan a buscar soluciones y descubren el concepto de DDD (Domain Driven Design), que sugiere establecer límites claros dentro del proyecto.

¿Qué es un contexto limitado?

  • Un contexto limitado es independiente y débilmente acoplado; aunque los componentes deben comunicarse, no deben depender excesivamente unos de otros.
  • Cada contexto tiene su propio lenguaje ubicuo y datos específicos, lo cual es crucial para mantener claridad y responsabilidad dentro del equipo.
  • Es importante designar un propietario explícito para cada contexto, facilitando así la gestión y responsabilidad.

Acoplamiento débil vs. fuerte

  • Se compara el acoplamiento fuerte (donde los contextos dependen mucho entre sí) con el acoplamiento débil (donde hay comunicación mínima pero efectiva).
  • En un buen diseño con acoplamiento débil, se puede utilizar un contexto sin necesidad del otro.

Lenguaje ubicuo

  • Se presenta el concepto de lenguaje ubicuo mediante ejemplos prácticos como Amazon, donde diferentes departamentos tienen distintas definiciones para "libro".
  • Esta variabilidad en las definiciones ayuda a identificar contextos limitados al observar cómo diferentes partes ven el mismo objeto desde perspectivas distintas.

Compartición de datos

  • Se discute cómo compartir datos entre servicios crea contratos implícitos problemáticos; cada contexto debe tener sus propios datos para evitar dependencias indeseadas.

Introducción a los Microservicios y Contextos Limitados

Experiencia Inicial con Microservicios

  • El ponente comparte su experiencia en una startup pequeña donde se recomendó el uso de microservicios, lo que resultó en un software poco confiable debido a la falta de experiencia del desarrollador.
  • Se menciona que aunque los microservicios son efectivos, su implementación es más adecuada para organizaciones grandes con recursos y conocimientos adecuados.

Desafíos de Implementar Microservicios

  • Los microservicios requieren un alto costo inicial de diseño; es crucial definir correctamente los límites y las formas de comunicación entre ellos.
  • La inconsistencia y la fiabilidad son problemas comunes al trabajar con microservicios, añadiendo complejidad al proyecto.

Costos y Complejidades Asociadas

  • Cambiar límites en microservicios puede ser costoso; mover componentes entre bases de código implica rediseño y nuevos patrones de comunicación.
  • La productividad puede verse afectada negativamente durante el proceso de refactorización si se descubren errores en los límites establecidos inicialmente.

Comunicación entre Contextos Limitados

Métodos para Comunicar Contextos

  • Se presentan dos patrones para la comunicación entre contextos limitados dentro de un monolito: mensajería y llamadas directas mediante interfaces bien definidas.
  • Se establece una similitud entre estos patrones y aquellos utilizados en microservicios, como eventos y mensajes.

Manejo Eficiente de Mensajes

  • Los mensajes pueden ser colocados en un bus de eventos o comandos, permitiendo un acoplamiento débil ya que el contexto consumidor solo necesita conocer el esquema del evento.
  • Persistir mensajes facilita la introducción de nuevos contextos al sistema sin complicaciones adicionales relacionadas con migraciones complejas.

Consideraciones sobre Asincronía

  • Es recomendable manejar eventos asíncronamente para evitar que el sistema se vuelva lento cuando múltiples procesos reaccionan a un solo evento.

Ejemplos Prácticos: Publicación y Consumo de Eventos

Ejemplo con PHP

  • Se presenta un ejemplo práctico utilizando PHP donde se publica un evento "orden realizada" en un bus de mensajes, mostrando cómo los contextos consumidores pueden reaccionar adecuadamente.

Introducción a la Inyección de Dependencias y Contextos

Concepto de Contexto Proveedor y Consumidor

  • Se discute la importancia de proporcionar un contexto adecuado, donde el contexto consumidor solo necesita conocer la interfaz expuesta por el contexto proveedor, sin preocuparse por los detalles de implementación.

Ejemplo de Repositorio de Usuario

  • Se menciona un repositorio público de usuarios que permite obtener un usuario por su ID, destacando que el nombre del repositorio podría no ser el más apropiado.

Métodos en el Objeto Usuario

  • El objeto devuelto tiene métodos como "get my name" y "give me the age", lo que ilustra cómo se interactúa con los datos sin conocer la implementación subyacente.

Pruebas Independientes del Contexto Proveedor

  • Las pruebas del contexto consumidor pueden realizarse sin depender del contexto proveedor, utilizando mocks basados en contratos para asegurar funcionalidad.

Pasos para Introducir Cambios en un Monolito Existente

Creación de un Mapa de Contextos

  • Es fundamental diseñar un mapa de contextos antes de comenzar a codificar. Este mapa ayuda a visualizar las dependencias e interacciones entre diferentes contextos.

Refactorización con Ayuda del IDE

  • Se sugiere mover clases a sus respectivos contextos utilizando herramientas disponibles en los IDE, facilitando así la refactorización necesaria.

Detección de Dependencias Indeseadas

  • Es importante identificar dónde un contexto depende excesivamente de otro para evitar acoplamientos fuertes. Esto se puede lograr mediante análisis estático del código.

Análisis Estático y Medición del Acoplamiento

Uso Cruzado entre Contextos

  • Se pueden medir dos aspectos: uso cruzado entre contextos y cuántas llamadas directas existen entre ellos. Esto proporciona información valiosa sobre las dependencias existentes.

Identificación de Problemas en Dependencias

  • Los problemas se identifican cuando hay requerimientos mutuos entre contextos (por ejemplo, A requiere B y viceversa), lo cual debe ser priorizado para su resolución.

Establecimiento de Objetivos Claros

  • Se recomienda establecer objetivos claros sobre la reducción del acoplamiento durante ciertos períodos, permitiendo al equipo trabajar hacia metas específicas.

Ventajas del Modelo Monolítico

Definición Clara de Límites

¿Cómo mejorar la arquitectura de software?

Ventajas de un sistema modular

  • La implementación de un sistema modular permite evitar las desventajas asociadas a los microservicios, simplificando la complejidad en DevOps y facilitando el establecimiento de límites claros en el diseño del software.
  • Si se descubre que el diseño inicial no es adecuado, se puede rediseñar fácilmente y aplicar pasos discutidos previamente, permitiendo mover clases y permitir temporalmente cierto acoplamiento durante el proceso de refactorización.

Refactorización más granular

  • La refactorización en un sistema modular es más granular que en microservicios, lo que facilita a los desarrolladores trabajar sin los altos costos iniciales asociados con la instalación de herramientas necesarias para microservicios.
  • A diferencia de los sistemas de microservicios, donde hay mucho trabajo manual involucrado para configurarlos, un sistema modular permite comenzar rápidamente con menos dependencias.

Comparación entre monolitos y microservicios

  • Existe una tendencia común en las empresas a alternar entre monolitos y microservicios debido a experiencias negativas previas. Un enfoque modular ofrece una solución intermedia efectiva entre estos dos extremos.
  • Al observar la productividad frente a la complejidad, se sugiere introducir límites cuando se note una disminución significativa en la productividad. Este es el momento adecuado para realizar mapeo contextual y refactorización.

Estrategia para escalar

  • Comenzar con un modelo modular permite validar ideas rápidamente. Una vez que se obtiene tracción y recursos suficientes, se puede proceder a refactorizar hacia una arquitectura más escalable.
  • Migrar desde un monolito modular hacia microservicios es factible cuando llega el momento adecuado; ya que al tener patrones de comunicación establecidos, esta transición resulta menos complicada.

Conclusión

Video description

http://dddeurope.com - https://twitter.com/ddd_eu - https://newsletter.dddeurope.com/ https://linkedin.com/company/domain-driven-design-europe Organised by Aardling (https://aardling.eu/) Introducing bounded contexts often is a great first step to get started with DDD. During this session you'll learn how a legacy application can be gradually refactored into bounded contexts. We'll also explore ways a team could keep track of their progress, and identify the level of decoupling of contexts within their application. About Robert Baelde The magic place where tech and business collide is where Robert finds the most interesting lessons to be learned. He has a passion for helping tech teams grow on multiple levels, from the low-level code to the overall processes in place. He's passionate about everything Event Sourcing and Domain Driven Design has to offer. Robert's talks are high-energy, practical, and to the point.