Arquitectura Reactiva II: Domain Driven Design

@gusariotti
Naranja X Tech
Published in
6 min readMay 31, 2021

Este artículo es la continuación del artículo que escribí “Introducción a la Arquitectura Reactiva parte I”, donde el curso de Cognitive Class me sirvió de guía para repasar puntos claves del Domain Driven Design (DDD).

Comenzando DDD es un enfoque de arquitectura usado para diseñar sistemas de grandes dimensiones. Los lineamientos, las reglas básicas y metas son compartidas con la arquitectura reactiva.
Lo que intenta es crear un canal de comunicación entre los expertos de negocio y los desarrolladores permitiendo partir un problema de gran complejidad (large domain) en pequeñas porciones que puedan ser más sencillas de comprender. Creando limites y determinando el alcance para esas partes dentro del dominio.
Muchas veces se combina su uso con arquitectura reactiva y en especial los microservicios reactivos, que tienen que tener bien claro los límites y su responsabilidad.

Dominio

  • Es un campo o esfera de conocimiento
  • En el contexto de software se refiere al negocio o idea que se está modelando
  • Los expertos son los que entienden el negocio
  • Se intenta crear un modelo que permita a los expertos y a los desarrolladores hablar un mismo lenguaje
  • El software debería ser una implementación de ese modelo

Lenguaje Ubicuo

Es un lenguaje común que permite a los desarrolladores hablar con los expertos de negocio. La terminología viene dada por los expertos y es implementada en el software. También previene hablar en términos técnicos cuando se conversa con negocio.

Subdominios

  • Los dominios grandes pueden ser divididos en subdominios
  • Se crean agrupando ideas, acciones y reglas
  • Algunos conceptos pueden existir en múltiples subdominios pero no ser lo mismo en cada uno (empezar distintos o evolucionar de manera diferente)

Contexto (Bounded Contexts)

Son una combinación entre el lenguaje ubicuo y el modelo de cada subdominio. También un buen punto de partida para definir microservicios reactivos.

Los siguientes puntos son clave:

  • Descubrir en profundidad y aprender sobre el dominio del problema
  • Desarrollar un lenguaje ubicuo y glosario de términos evitando confusiones
  • Identificar los distintos subdominios y universos del problema
  • Definir los contextos a partir de estos subdominios y representar sus relaciones en un mapa de contextos
  • Contar con los expertos del dominio en todo el proceso de consultoría

Ejemplo del libro de Fowler:

Anteriormente DDD se encargaba en este proceso de encontrar objetivos o conceptos para poder dividir en subdominios pero actualmente la tendencia es determinar que eventos o reacciones tienen esos objetos en el problema que estamos estudiando, visualizar sus actividades, etc. (event first domain driven design)

Capas anticorrupción (ACL)

Una capa anticorrupción consiste en asignar un dominio a otro para que los servicios que usan el segundo dominio no tengan que estar “dañados” por los conceptos del primero. Las ACL son para los modelos de dominio lo que los adaptadores son para las clases, simplemente sucede en un nivel diferente.
Cuando se pasa de un bounded context a otro es necesario hacer transformaciones en los objetos para garantizar el correcto entendimiento de ese objeto en el otro contexto.

Mapas de contexto

Los mapas son una herramienta para visualizar las relaciones que tienen los distintos contextos indicando que tipo de relación si necesitamos con una etiqueta.

Tipos de actividades dentro del dominio

Comandos (commands)

  • Descubrir en profundidad y aprender sobre el dominio del problema
  • Representan una solicitud de realizar una determinada acción
  • Usualmente va dirigida a un destino especifico
  • Hace un cambio en el estado del dominio
  • Esta accion solicitada todavía no pasó y no puede ser rechazada

Ej: agregar un producto a la orden

Eventos (events)

  • Representan acciones que ocurrieron en el pasado
  • No puede ser rechazado porque ya ocurrió, se puede decidir ignorarlo pero es algo que realmente pasó
  • Pueden ser transmitidos a muchos destinos
  • Registran estados en el dominio, son a menudo el resultado de un comando

Ej: el producto se agregó a la orden

Consultas (queries)

  • Representan un pedido de información
  • Siempre esperan una respuesta (comandos y eventos no necesariamente dan respuesta)
  • No alteran el estado del dominio
  • Generalmente tienen un destino especifico

Ej: obtener el detalle de una orden

Comandos, eventos y consultas representan mensajes en un sistemas reactivo. Forman la API del microservicio que repesenta ese bounded context.

Tipos de objetos dentro del dominio

Objetos de Valor (Value Object)

  • Se define por sus atributos y son inmutables
  • Dos Value Object son idénticos si tiene exactamente los mismos atributos
  • Los mensajes en sistemas reactivos son implementados como Value Object
  • Pueden contener lógica de negocio para devolver ciertos valores del objeto

Entidades (Entities)

  • Es definida por una clave única
  • Puede cambiar sus atributos pero no cambiar su clave.
  • Pueden contener lógica de negocio

Agregados (Aggregates)

  • Son una colección de objetos del dominio conectados a una entidad raíz o padre

Abstracciones

Servicios (services)

  • La lógica de negocio que no puede ser encapsulada en value object o entities puede estar en la abstracción de un servicio
  • Deben ser stateless (no guardar el estado)

Factorias (factories)

  • La lógica de crear nuevos objetos del dominio a veces es compleja y puede requerir las factorias
  • Puede requerir recursos externos
  • Usualmente se implementa como una interfaz del dominio

Repositorios (repositories)

  • Contemplan la lógica de recuperar objetos del dominio
  • Permiten manipulas los objetos, modificarlos, etc
  • A veces los repositorios tienen la capacidad de crear y no son necesarias las factories, pero depende de la lógica y la implementación

Arquitectura Hexagonal (Hexagonal Architecture)

La Arquitectura Hexagonal, dada a conocer por Alistair Cockburn — y también conocida como arquitectura de puertos y adaptadores — , tiene como principal motivación separar nuestra aplicación en distintas capas o regiones con su propia responsabilidad. De esta manera consigue desacoplar capas de nuestra aplicación permitiendo que evolucionen de manera aislada. Además, tener el sistema separado por responsabilidades nos facilitará la reutilización.

Gracias a este desacoplamiento obtenemos también la ventaja de poder testear estas capas sin que intervengan otras externas, falseando el comportamiento con dobles de pruebas, por ejemplo.

Esta arquitectura se suele representar con forma de hexágono, pero el número de lados no es lo que importa, sino lo que estos representan. Cada lado representa un puerto hacia dentro o fuera de la aplicación. Por ejemplo, un puerto puede ser el HTTP, y hacer peticiones a nuestra aplicación, otro puerto puede ser el SOAP y también hace peticiones a la aplicación. Otro puede ser un servidor de base de datos en donde persistir los datos de nuestro dominio.

Arquitectura Hexagonal

La Arquitectura Hexagonal propone que nuestro dominio sea el núcleo de las capas y que este no se acople a nada externo. En lugar de hacer uso explícito y mediante el principio de inversión de dependencias nos acoplamos a contratos (interfaces o puertos) y no a implementaciones concretas.

A grandes rasgos, y sin mucho detalle, lo que propone es que nuestro núcleo sea visto como una API con unos contratos bien especificados. Definiendo puertos o puntos de entrada e interfaces (adaptadores) para que otros módulos (UI, BBDD, Test) puedan implementarlas y comunicarse con la capa de negocio sin que ésta deba saber el origen de la conexión.

Esto es lo llamado puertos y adaptadores, que podrían ser definidos de la siguiente manera:

  • Puerto: definición de una interfaz pública.
  • Adapter: especialización de un puerto para un contexto concreto.

Al ser una arquitectura que fomenta que nuestro dominio sea el núcleo de todas las capas (o regiones), y que no se acople a nada externo, encaja muy bien con la idea de DDD.

Podríamos decir que DDD se basa en la Arquitectura Hexagonal.

--

--