Be Software Architecture Wise
Be Wise Apps

Read in English · Lire en français · Auf Deutsch lesen

Sección 5.7 de 5.8 · Intermedio · 26 min de lectura

Diseño estratégico guiado por el dominio: contextos delimitados y mapas de contextos

Videolección

5 min · narrado en inglés, con subtítulos
Solo escuchar (audio)
Leer la transcripción

Todos los estilos de este capítulo necesitan límites. En esta lección aprenderás el método más usado para encontrarlos en el propio negocio: el diseño estratégico guiado por el dominio.

En un hospital, la palabra paciente significa algo distinto para cada departamento. Para la recepción, es un nombre, una dirección y una cita. Para la planta, es una cama, una medicación y unas constantes. Para la oficina de facturación, es una aseguradora y una factura. Un único formulario gigante que sirviera a todos sería enorme, y todos se pelearían por él. Funciona mejor cuando cada departamento mantiene su propio registro sencillo y todos acuerdan cómo pasarse la información.

El diseño guiado por el dominio, o DDD, lo presentó Eric Evans en 2003. Su argumento es que los problemas más difíciles del software de negocio no suelen ser técnicos, sino de comprensión del dominio. Así que el software se construye en torno a un modelo del dominio, desarrollado con expertos del dominio. Todo el mundo usa un vocabulario compartido, el lenguaje ubicuo, en las conversaciones, los documentos, las pruebas y el código. Cuando dos grupos usan la misma palabra con significados distintos, has encontrado indicios de dos modelos diferentes. Ahí es donde empiezan los límites.

Primero, divide el negocio en subdominios y clasifícalos. El dominio central es lo que diferencia al negocio. Para una empresa de reparto de comida, probablemente sea el despacho: asignar pedidos a repartidores y predecir las horas de llegada. Merece a tus mejores personas y tu modelado más cuidadoso. Un subdominio de soporte es específico y necesario, pero no es una fuente de ventaja, como la gestión de cartas. Merece un diseño sólido pero más sencillo. Un subdominio genérico es un problema que comparten muchas empresas, como los pagos o la identidad. Normalmente deberías comprarlo, o construir una capa fina sobre una solución existente.

Ahora, la idea clave. Un contexto delimitado es un límite dentro del cual un modelo y un lenguaje se aplican de forma coherente. Aquí, un mismo pedido de un cliente se ve de forma distinta en tres contextos. En Pedidos, es un carrito con precios, descuentos y un estado de pago. En Despacho, es un trabajo de reparto: una recogida, un destino, una hora en que la comida estará lista y un repartidor. Y en Cocina, es una comanda: platos, notas, alérgenos y tiempo de preparación. Solo comparten el ID del pedido y los eventos que pasan entre ellos. Cada modelo se mantiene pequeño, porque tiene un solo propósito.

Un mapa de contextos muestra los contextos y cómo se relacionan. Este es el de la plataforma de reparto de comida, donde una única clase Order compartida había crecido hasta tener noventa y cuatro campos. El arquitecto organizó un taller de event storming de dos días, en el que expertos del negocio e ingenieros colocaron los eventos del dominio en una línea de tiempo, y a partir de él dibujó este mapa. Despacho es el dominio central. Pedidos y Despacho forman una asociación: triunfan o fracasan juntos, así que planifican y lanzan el traspaso de forma conjunta. Catálogo de cartas abastece a Pedidos en una relación de cliente y proveedor: las necesidades de Pedidos entran en el backlog de Cartas. Hacia los sistemas que no controla, un contexto construye una capa anticorrupción, que traduce para que el modelo ajeno no pueda filtrarse. Cartas lo hace con los sistemas de punto de venta de los restaurantes, y Pagos con el proveedor de pagos. Despacho, en cambio, es conformista: usa el modelo del proveedor de mapas tal como es. Es una elección deliberada, porque traducirlo costaría más de lo que ahorra. Pagos ofrece a todos una única API abierta y documentada, y los eventos de pedido tienen un formato publicado y versionado.

Los contextos delimitados son la mejor guía para los límites de módulos y servicios. Cada uno tiene su propio modelo, su lenguaje, sus datos e, idealmente, un único equipo propietario. En la plataforma, cada contexto se convierte primero en un módulo de un monolito modular, con su propio esquema. Dentro de cada módulo, la estructura hexagonal de la sección cinco punto seis mantiene el modelo independiente de la infraestructura. Despacho, con necesidades de escalado y de lanzamiento muy distintas, es el primer candidato a convertirse más adelante en un servicio separado. Su límite ya tiene la forma adecuada. Por eso muchos profesionales dicen: encuentra primero los contextos y decide después el despliegue. Los servicios que atraviesan los contextos producen un monolito distribuido fuertemente acoplado.

La sección completa trata los ocho patrones de relación, cómo funciona el event storming y piezas básicas como los agregados. A continuación, en la sección cinco punto ocho, la última de este capítulo, nos preguntamos cuándo un monolito es la respuesta correcta. Nos vemos allí.

Lo que necesitas saber

Por qué el diseño guiado por el dominio tiene su lugar en un capítulo sobre estructura

Todos los estilos de este capítulo necesitan límites. Un monolito modular necesita límites entre módulos; los microservicios del Capítulo 6 necesitan límites entre servicios; incluso una aplicación hexagonal necesita saber qué pertenece al interior del hexágono. El diseño guiado por el dominio (DDD) es el método más usado para encontrar esos límites en el propio dominio de negocio, y no en capas técnicas.

Eric Evans lo presentó en Domain-Driven Design: Tackling Complexity in the Heart of Software (Addison-Wesley, 2003). Su argumento es que, en la mayor parte del software de negocio, los problemas más difíciles no son técnicos, sino de comprensión del dominio: qué es realmente una póliza, un siniestro, una entrega o un reembolso, y qué reglas lo rigen. Por tanto, el software debería construirse en torno a un modelo del dominio diseñado de forma deliberada, desarrollado conjuntamente por desarrolladores y expertos del dominio, y ese modelo debería protegerse para que no se confunda con otros modelos. En 2015 Evans publicó una breve DDD Reference que resume los patrones y añade algunos, como la asociación (partnership) y la gran bola de barro (big ball of mud) como patrones del mapa de contextos, y los eventos de dominio como pieza básica.

El DDD tiene dos mitades. El diseño estratégico divide un dominio grande en subdominios y contextos delimitados y traza las relaciones entre ellos; es arquitectura, y es el tema principal aquí. El diseño táctico ofrece piezas básicas (entidades, objetos de valor, agregados y otras) para escribir el modelo dentro de un contexto; es diseño, y se trata brevemente.

Lenguaje ubicuo

Un lenguaje ubicuo es un vocabulario compartido, construido entre desarrolladores y expertos del dominio, que se usa de forma coherente en las conversaciones, los documentos, las pruebas y el código. Si los despachadores dicen que un repartidor va "apilado" cuando lleva dos pedidos del mismo restaurante, entonces el código dice stack, no multiOrderAssignment. Cuando un término resulta ambiguo o incómodo, el equipo cambia el lenguaje y el código a la vez.

Parece una cuestión de nombres, pero tiene consecuencias arquitectónicas. La traducción entre las palabras del negocio y las palabras del código es donde nacen los malentendidos y, por tanto, los defectos. Y en el momento en que dos grupos usan la misma palabra con significados distintos, has encontrado indicios de dos modelos diferentes, que es el punto de partida de los contextos delimitados.

Subdominios: centrales, de soporte y genéricos

El dominio de negocio en su conjunto se divide en subdominios: áreas de actividad como las cartas, los pedidos, los pagos y el despacho. Los profesionales los clasifican en tres tipos, a partir de la distinción de Evans entre el dominio central y los subdominios genéricos; la división en tres con los subdominios de soporte la popularizaron autores posteriores, en especial Vaughn Vernon en Implementing Domain-Driven Design (2013).

El dominio central (core domain) es lo que diferencia al negocio de sus competidores y la razón por la que merece la pena construir el software. Para una empresa de reparto de comida, probablemente sea el despacho: asignar pedidos a repartidores y predecir las horas de llegada. Un subdominio de soporte es específico del negocio y necesario, pero no es una fuente de ventaja: la gestión de cartas, el alta de repartidores. Un subdominio genérico es un problema que comparten muchas empresas y para el que existen buenas soluciones: pagos, identidad, correo electrónico y SMS.

La clasificación es una decisión de inversión. El dominio central merece a las personas con más experiencia, el modelado más rico y un código que sea totalmente propio, porque ahí es donde un software mejor se convierte directamente en ventaja para el negocio. Los subdominios de soporte merecen diseños sólidos pero más sencillos, a menudo un módulo en capas sin complicaciones. Los subdominios genéricos normalmente deberían comprarse, usarse como servicio o construirse como adaptadores finos sobre componentes de código abierto: construir tu propio proveedor de identidad es esfuerzo invertido donde no puedes ganar. La clasificación también cambia con el tiempo; una capacidad de soporte puede pasar a ser central cuando cambia la estrategia del negocio.

Contextos delimitados

Un contexto delimitado (bounded context) es un límite explícito dentro del cual un modelo, y un lenguaje ubicuo, se aplica de forma coherente. Dentro de él, "pedido" tiene exactamente un significado. Fuera de él, la misma palabra puede significar otra cosa, y eso es aceptable, porque cada modelo está diseñado para un propósito. Evans observó que intentar unificar en uno solo el modelo de un sistema grande no es ni viable ni rentable; el intento produce enormes clases compartidas que sirven mal a todos los propósitos y que todos los equipos tienen que modificar.

Los subdominios y los contextos delimitados son cosas distintas, aunque a menudo coinciden. Un subdominio es parte del problema: existe en el negocio haya o no software. Un contexto delimitado es parte de la solución: un límite que eliges para un modelo y, normalmente, para un código y unos datos que pertenecen a un equipo. Lo ideal es un contexto delimitado por subdominio, pero los sistemas heredados suelen tener un contexto que abarca varios subdominios, y un subdominio grande puede necesitar varios contextos.

Una palabra, tres modelos

La palabra pedido significa cosas distintas en tres contextos delimitados de una plataforma de reparto; cada uno tiene su propio modelo, unidos por un ID de pedidoContexto PedidosPedido = carrito, precios,descuentos, estado de pagoestados: borrador, hecho,pagado, canceladoContexto DespachoReparto = recogida,destino, hora lista, repartidorestados: en espera, asignado,recogido, entregadoContexto CocinaComanda = platos, notas,alérgenos, preparaciónestados: recibida, cocinando,listaSolo se comparte: el ID del pedido (A-17) y los eventos que pasan entre contextosCada modelo es simple porque tiene un solo propósito
"Pedido" significa un carrito con precios para Pedidos, un trabajo de recogida y entrega para Despacho y una lista de platos que cocinar en el contexto Cocina; cada modelo se mantiene pequeño porque tiene un solo propósito.

Mapas de contextos

Un mapa de contextos muestra los contextos delimitados de un sistema y las relaciones entre ellos. Las relaciones describen tanto la integración técnica como el poder y la comunicación entre los equipos, por eso el mapeo de contextos trata tanto de organizaciones como de código. Es una aplicación directa de la ley de Conway: el mapa muestra dónde deben coincidir los caminos de comunicación de la organización y los caminos de integración del sistema.

Muchas relaciones son upstream/downstream (aguas arriba/aguas abajo): las decisiones del contexto upstream afectan al downstream, pero no al revés. El equipo downstream tiene entonces que elegir cómo arreglárselas, y esa elección es lo que nombra la mayoría de los patrones.

Patrones de relación del mapa de contextos

PatrónQué significaQuién se adapta a quiénEjemplo de reparto de comida
Asociación (partnership)Dos equipos triunfan o fracasan juntos, así que planifican conjuntamente y evolucionan su interfaz a la vez.Ambos, de mutuo acuerdoPedidos y Despacho lanzan juntos el traspaso del pedido a la entrega.
Núcleo compartido (shared kernel)Dos contextos comparten una parte pequeña y acordada explícitamente del modelo y de su código; los cambios necesitan el consentimiento de ambos equipos.Ambos, con cuidadoDespacho y Alta de repartidores comparten una biblioteca diminuta de perfil de repartidor (tipo de vehículo, ID del repartidor).
Cliente-proveedorEl equipo upstream (proveedor) se compromete a atender las necesidades del equipo downstream (cliente), que forman parte de su planificación.Upstream sirve a downstreamCatálogo de cartas suministra cartas y precios a Pedidos, y las necesidades de Pedidos entran en el backlog de Cartas.
ConformistaEl equipo downstream adopta el modelo upstream tal como es, porque no puede influir en él y traducirlo no compensa el costo.Downstream se adaptaDespacho usa directamente el modelo de rutas y ubicaciones del proveedor de mapas.
Capa anticorrupciónEl equipo downstream construye una capa de traducción para que el modelo upstream no pueda filtrarse en el suyo.Downstream traduceCartas traduce decenas de formatos de punto de venta de restaurantes a su propio modelo de carta; Pagos aísla la API del proveedor.
Servicio de host abierto (open host service)El contexto upstream ofrece un protocolo o una API bien definidos para todos los consumidores, en lugar de una integración a medida para cada uno.Upstream publica una vezPagos ofrece una única API de pagos documentada a Pedidos, a reembolsos y a suscripciones.
Lenguaje publicadoUn formato de intercambio documentado y compartido, que a menudo se usa con un servicio de host abierto.Ambos usan el lenguajeLos eventos de pedido (OrderPlaced, OrderCancelled) tienen un esquema versionado y documentado.
Caminos separados (separate ways)Los contextos no se integran en absoluto, porque el beneficio es menor que el costo.NingunoLos informes de nómina de los repartidores se hacen en una herramienta de finanzas aparte, alimentada por una exportación mensual, sin integración en tiempo real.

Dos de estos patrones merecen especial atención. Una capa anticorrupción (ACL) es un conjunto de adaptadores y traductores que construye un contexto downstream para que un modelo ajeno, a menudo un sistema heredado o un proveedor externo, no pueda filtrarse en su propio modelo. Es la misma idea que el adaptador conducido de la Sección 5.6, aplicada entre contextos, y es la opción por defecto para integrarse con cualquier cosa que no controlas. Un servicio de host abierto (open host service) junto con un lenguaje publicado es la forma que tiene el contexto upstream de servir bien a muchos consumidores: un único protocolo documentado y versionado en lugar de una integración a medida para cada uno. Un núcleo compartido (shared kernel) debe seguir siendo pequeño; uno grande vuelve a convertir dos contextos en uno con dos equipos discutiendo por él, y la referencia de Evans de 2015 añade la gran bola de barro (big ball of mud) como etiqueta honesta para una zona sin ningún límite claro, que hay que contener en lugar de ampliar.

Event storming: descubrir los contextos

Los límites se descubren con los expertos del dominio, no se diseñan en solitario. El event storming, creado por Alberto Brandolini y descrito por primera vez en su blog en 2013, es el formato de taller más popular para ello. Las personas que conocen el negocio y las que construyen el software se colocan ante una larga pared de papel y escriben eventos de dominio (cosas que han pasado, en pasado: Pedido realizado, Repartidor asignado, Comida recogida) en notas adhesivas naranjas, que colocan en una línea de tiempo.

Después, el grupo añade los comandos que causan los eventos, las personas y los sistemas externos implicados, las políticas que reaccionan a los eventos ("cada vez que se realiza un pedido, buscar un repartidor") y, lo que es crucial, los puntos calientes (hot spots) donde la gente no está de acuerdo o nadie lo sabe. Los grupos de eventos que comparten un lenguaje y un propósito sugieren contextos delimitados; los lugares donde la misma palabra se usa de forma distinta sugieren límites; los lugares donde se produce un traspaso sugieren puntos de integración. Una sesión de visión global (big picture) para todo un negocio dura uno o dos días y casi no necesita más preparación que las personas adecuadas y mucho espacio en la pared.

Los patrones tácticos, en breve

Dentro de un contexto delimitado, el DDD ofrece piezas básicas para el modelo. Una entidad tiene una identidad que persiste mientras cambian sus atributos: un pedido es el mismo pedido después de que cambie su estado. Un objeto de valor no tiene identidad y se define solo por sus valores: dos objetos Money(12.50, "GBP") son intercambiables, y los objetos de valor suelen ser inmutables. Un evento de dominio registra algo significativo que ha pasado en el dominio.

Un agregado es un grupo de entidades y objetos de valor que se trata como una sola unidad para los cambios, con una entidad como raíz. El código externo solo puede guardar referencias a la raíz y solo debe modificar el agregado a través de ella, de modo que la raíz pueda hacer cumplir las invariantes del agregado (reglas que deben cumplirse siempre, como "no se pueden añadir artículos después de realizar un pedido"). Una transacción debería modificar un solo agregado; a los demás agregados se les hace referencia por su ID y se actualizan mediante eventos de dominio, lo que convierte a los agregados en la unidad natural de consistencia y, más adelante, de distribución. Un repositorio carga y guarda agregados completos y, para el dominio, parece una colección; su interfaz es un puerto conducido en términos hexagonales.

from dataclasses import dataclass, field
from decimal import Decimal

@dataclass(frozen=True)
class Money:                               # value object: equal if values equal
    amount: Decimal
    currency: str
    def __add__(self, other):
        if other.currency != self.currency:
            raise ValueError("currency mismatch")
        return Money(self.amount + other.amount, self.currency)
    def times(self, n: int):
        return Money(self.amount * n, self.currency)

@dataclass
class OrderLine:                           # entity inside the aggregate
    dish_id: str
    qty: int
    price: Money

@dataclass
class Order:                               # aggregate root
    id: str
    restaurant_id: str                     # other aggregates referenced by ID only
    lines: list[OrderLine] = field(default_factory=list)
    status: str = "draft"
    events: list = field(default_factory=list)

    def add(self, dish_id, qty, price):
        if self.status != "draft":
            raise ValueError("order already placed")    # invariant
        self.lines.append(OrderLine(dish_id, qty, price))

    def place(self, minimum: Money):
        total = Money(Decimal(0), minimum.currency)
        for line in self.lines:
            total = total + line.price.times(line.qty)
        if total.amount < minimum.amount:
            raise ValueError("below restaurant minimum")  # invariant
        self.status = "placed"
        self.events.append({"type": "OrderPlaced", "order_id": self.id, "total": str(total.amount)})
Un agregado Order: un objeto de valor (Money), una entidad (OrderLine), la raíz del agregado que hace cumplir las invariantes y un evento de dominio que se registra cuando se realiza el pedido.

El ejemplo mantiene pequeño el agregado, hace referencia al restaurante por su ID en lugar de contener un objeto restaurante y hace cumplir sus reglas en métodos en lugar de dejárselas a quien lo llama. Un error habitual es lo contrario: agregados tan grandes que el cambio de cualquier usuario bloquea las mismas filas, u objetos de dominio que son solo bolsas de getters y setters mientras las reglas viven en clases de servicio (Martin Fowler lo llama modelo de dominio anémico).

Ejemplo práctico

Ejemplo práctico: un mapa de contextos para la plataforma de reparto de comida

La plataforma ha crecido hasta unos 60 ingenieros en ocho equipos, y parece que cada cambio toca la clase compartida Order, que ya tiene 94 campos. El arquitecto organiza un taller de event storming de dos días con gestores de producto, personal de operaciones, soporte a restaurantes e ingenieros, y después dibuja el mapa de contextos que se muestra abajo.

1. Encontrar los subdominiosA partir de la línea de tiempo de eventos: gestión de cartas, pedidos y proceso de pago, pagos, despacho (asignar repartidores a pedidos y predecir las horas de llegada), alta de repartidores, notificaciones a clientes, integración con restaurantes.
2. ClasificarlosEl despacho es el dominio central: las entregas más rápidas y baratas son lo que gana clientes y restaurantes. Las cartas, los pedidos y el alta de repartidores son de soporte: necesarios y específicos de este negocio, pero no es ahí donde compite. Los pagos y las notificaciones son genéricos: problemas resueltos, que es mejor comprar o construir de forma mínima sobre un proveedor.
3. Dibujar los contextos delimitadosCada subdominio tiene su propio modelo. El "pedido" de Pedidos (carrito, precios, estado de pago) se separa del "trabajo de reparto" de Despacho (recogida, destino, hora en que la comida estará lista) y de la "comanda" de la vista de cocina del restaurante. La clase de 94 campos se convierte en tres modelos enfocados unidos por el ID del pedido.
4. Nombrar las relacionesPedidos y Despacho: asociación. De Cartas a Pedidos: cliente-proveedor. Pagos: servicio de host abierto con un lenguaje publicado, y una capa anticorrupción hacia el proveedor externo. Cartas: capa anticorrupción hacia los sistemas de punto de venta de los restaurantes. Despacho: conformista con la API de mapas, una elección deliberada, porque traducir su rico modelo costaría más de lo que ahorra.
5. Decidir la inversiónLos mejores ingenieros y el modelado más cuidadoso van a Despacho. Pagos usa un proveedor a través de un adaptador fino. Notificaciones usa un servicio de mensajería comprado.
6. Decidir el despliegueLos contextos se convierten primero en módulos de la aplicación existente, que pasa a ser un monolito modular (Sección 5.3), cada uno con su propio esquema e interfaz pública. Despacho, que tiene necesidades de escalado y de lanzamiento muy distintas, es el primer candidato a convertirse más adelante en un servicio separado.

Clasificar Pedidos como de soporte sorprendió a algunas partes interesadas. El criterio no es la importancia (la empresa no puede funcionar sin pedidos), sino la diferenciación: ¿un mejor modelo de pedidos le ganaría al negocio más clientes que un mejor modelo de despacho?

La relación conformista con el proveedor de mapas es un compromiso consciente, recogido en un registro de decisiones, no un accidente. Si el proveedor cambia o se sustituye, Despacho lo notará.

El mapa de contextos

Mapa de contextos de la plataforma de reparto de comida: contextos delimitados, sistemas externos y el patrón de relación de cada conexiónPOS restauranteexterno, muchas marcasAPI mapasexternoCat. de cartasde soportePedidosde soporteDespachonúcleoPagosgenéricoNotificacionesgenéricoAlta de repartidoresde soporteProveedor de pagoexternoUDACL en CartasUDConformistaUDcliente /proveedorAsociación (partnership)DUOHS / PLeventos pedido(lenguajepublicado)Núcleo comúnDUACL en PagosU = upstream, D = downstreamCaja coral: subdominio central; caja gris: sistema externoFlecha a trazos: eventos asíncronos
Cada línea indica el patrón de relación; U y D marcan upstream y downstream, y las capas anticorrupción están en el lado downstream, hacia los sistemas que la plataforma no controla.

Los contextos delimitados como límites de módulos y servicios

Los contextos delimitados son la mejor guía disponible para decidir dónde trazar los límites de los módulos en un monolito y los límites de los servicios en un sistema distribuido. Un contexto tiene su propio modelo, su propio lenguaje, sus propios datos e, idealmente, un único equipo propietario, que son exactamente las propiedades que hacen que un módulo sea cohesivo y esté poco acoplado. En un monolito modular, cada contexto se convierte en un módulo con su propio esquema; dentro de él, la estructura hexagonal de la Sección 5.6 mantiene el modelo independiente de la infraestructura.

Si más adelante hay que desplegar un contexto por separado, su límite ya tiene la forma adecuada para un servicio, y sus relaciones en el mapa de contextos te dicen cómo debe ser la integración. Por eso muchos profesionales recomiendan encontrar primero los contextos y decidir después el despliegue. Lo contrario también se cumple: los servicios que atraviesan los contextos delimitados (un "servicio de pedidos" en el que escriben todos los contextos) producen el monolito distribuido fuertemente acoplado que se trata en la Sección 6.3. Ten en cuenta también que un contexto delimitado no es automáticamente un microservicio; un contexto puede desplegarse como varios servicios, y varios contextos pequeños pueden compartir un mismo despliegue.

Lo que aporta y lo que cuesta el DDD estratégico

AspectoEfectoMotivo
Modificabilidad dentro de un contextoAltoUn modelo, un lenguaje y un propietario: los cambios se quedan en un sitio y es fácil razonar sobre ellos.
Autonomía de los equiposAltoLos límites de los contextos coinciden con los límites de los equipos, así que los equipos pueden cambiar sus modelos sin negociar cada cambio.
Encaje entre el software y el negocioAltoEl lenguaje ubicuo y el modelado conjunto reducen los errores de traducción entre los expertos y el código.
Esfuerzo inicial y continuoDe media a altaLas sesiones de modelado, el tiempo de los expertos del dominio, las capas de traducción y el mantenimiento de los contratos cuestan esfuerzo.
Duplicación e integración de datosCosto medioCada contexto guarda su propia copia de lo que necesita, que debe mantenerse sincronizada mediante eventos o API.
Valor para dominios sencillosBajoEn sistemas basados sobre todo en CRUD y con poca lógica, el DDD táctico en particular añade ceremonia con poco retorno.

Comprueba lo que has entendido

¿Cuál es la diferencia entre un subdominio y un contexto delimitado?

Un subdominio es parte del problema de negocio y existe haya o no software; un contexto delimitado es un límite elegido en la solución, dentro del cual se aplica un modelo. Lo ideal es que coincidan, pero no tienen por qué.

Tu equipo se integra con un sistema de facturación heredado cuyo modelo es confuso y que no puedes cambiar. ¿Qué patrón del mapa de contextos protege tu modelo?

Una capa anticorrupción: traductores de tu lado que convierten el modelo heredado a tus propios términos, para que no pueda filtrarse en tu contexto.

¿Por qué una transacción debería modificar normalmente un solo agregado?

Porque el agregado es la unidad cuyas invariantes deben cumplirse en conjunto; modificar varios a la vez crea bloqueos grandes y acoplamiento, mientras que los demás agregados pueden actualizarse mediante eventos de dominio, lo que además permite distribuirlos más adelante.

¿Por qué los pagos suelen ser un subdominio genérico para una empresa de reparto de comida?

Porque cobrar pagos es un problema resuelto que comparten muchas empresas y no es donde compite la empresa, así que es mejor comprarlo o construirlo de forma mínima sobre un proveedor que modelarlo en profundidad.

Siguiente · 5.8Elegir un monolitoMonolithFirst, la prima de los microservicios y el monolito majestuoso; cuándo una sola unidad de despliegue es la opción correcta, hasta dónde escala un monolito, las señales de que ha llegado el momento de dividirlo y una guía de decisión para los estilos del Capítulo 5.Continuar →

Fuentes y lecturas recomendadas

¿Tienes una pregunta sobre esta sección? ArchitectBot, el asistente de estudio con IA del curso, responde primero a partir del curso.

Pregunta: “Nuestra tabla 'Customer' la usan ventas, soporte y facturación, y nadie se atreve a cambiarla. ¿Cómo usaría los contextos delimitados para desenredarla sin reescribirlo todo de golpe?”