Episodio 3

Context mapping y anti-corruption layer

lectura · 15 mindominio · BCPS Bankoperación · transferencia a otro banco

Un correo de otro banco

Un lunes llega un correo del banco de Luis: «Estrenamos la versión 2 de nuestra API. El campo beneficiario pasa a llamarse destinatario y añadimos un estado nuevo, 3 = en revisión. El antiguo 3 (liquidada) pasa a ser el 4».

En BCPS Bank, el equipo de Transferencias hace la cuenta de lo que hay que tocar. El envío, claro. Pero también el modelo de Transferencias, que guarda el estadoBancoLuis tal cual. Y el evento público TransferenciaCompletada, que lo lleva dentro. Y Notificaciones, que lo usa para el texto del aviso. Cuatro sitios, dos equipos, por un cambio en un banco que no es el nuestro.

Los contextos del episodio 2 no viven aislados: se relacionan, y cada relación es de un tipo, con consecuencias para los equipos. Dibujar esas relaciones es el context mapping.

El banco de Luis cambia su API

Transferencias manda 100 € de Ana a Luis. A la izquierda, sin nada en medio: el modelo del banco de Luis se usa tal cual. A la derecha, un traductor en la frontera. Envía una transferencia con la API v1, cambia a la v2 (mira el código: se marcan las líneas que ha habido que cambiar) y envía otra. Luego haz que el banco la ponga en revisión.

Qué ha pasado

El modelo de otro se cuela en el tuyo

Sin traductor, todo funciona con la API v1… y aun así ya hay un problema: la palabra estadoBancoLuis está en el modelo de Transferencias, en su lógica (if (estado === 3)), en su evento público y en el aviso que recibe Ana: «Tu transferencia está en estado 3».probar en el laboratorio El lenguaje de otro banco se ha colado hasta la app.

El día que ese banco cambia su API, se paga:probar en el laboratorio

La anti-corruption layer

Una anti-corruption layer (ACL) es una capa que traduce en la frontera entre tu modelo y otro que no controlas. Hacia fuera, habla el idioma del otro (destinatario, códigos numéricos); hacia dentro, el tuyo (liquidada, pendiente, rechazada). En el panel de la derecha, Transferencias ni se entera de que existe una API v2: cambia el traductor, en un solo sitio, y el «3 = en revisión» se convierte en «pendiente». Nadie publica nada todavía, y Ana no recibe un aviso falso.

No es gratis: es código que mantener, y una traducción más en cada llamada. Por eso se usa donde el otro modelo es ajeno, cambia sin avisar o es malo. Un banco externo cumple las tres.

El mapa completo

La ACL es solo una de las relaciones posibles. Este es el mapa de BCPS Bank con el tipo de cada una. U y D marcan quién está arriba (upstream, el que manda en el modelo) y quién abajo (downstream, el que se adapta).

RelaciónQué implicaEn BCPS Bank
Cliente-proveedor (C/S)El de arriba atiende las necesidades del de abajo; negocian los cambiosClientes → Cuentas (ClienteVerificado); Antifraude → Tarjetas (llamada síncrona)
Servicio anfitrión abierto + lenguaje publicado (OHS/PL)Un protocolo abierto y documentado para todos, en vez de uno a medida para cada consumidorLos eventos de Cuentas (MovimientoRegistrado), con su esquema versionado (ep. 6 de eventos)
Conformista (CF)El de abajo acepta el modelo del de arriba tal cualNotificaciones y Fidelización con los eventos de Transferencias y Tarjetas
Núcleo compartido (SK)Un trozo pequeño de modelo común, que solo cambia de acuerdoLos tipos Importe e IBAN, entre Cuentas y Transferencias
Anti-corruption layer (ACL)Un traductor que protege tu modelo del de otroTransferencias ↔ banco de Luis

Fíjate en el conformista, que es el contrapunto a la ACL. Notificaciones acepta los eventos de Transferencias sin traducir nada, y está bien: el evento es estable, lo publicamos nosotros y Notificaciones solo necesita un texto. Montar una ACL ahí sería traducir por traducir. Adaptarse al de arriba sale más barato cuando su modelo es razonable; la ACL compensa cuando no lo es, o cuando no controlas cuándo cambia.

Subdominios: dónde invertir

Pulsa «Ver subdominios» en el mapa. Cada contexto resuelve un tipo de problema, y no todos merecen el mismo esfuerzo:

Eventos de dominio y eventos de integración

Pulsa Transferencias en el mapa. Dentro de su contexto pasan cosas que a nadie más le importan: EnvíoAlBancoReintentado, RespuestaDelBancoRecibida. Son eventos de dominio: hablan el lenguaje interno y pueden cambiar cuando el equipo quiera. TransferenciaCompletada, en cambio, es un evento de integración: sale del contexto, otros lo consumen y es un contrato (un lenguaje publicado). La simulación enseña qué pasa cuando un detalle interno, o de otro banco, acaba en el contrato público: todos los que lo consumen heredan el problema.

Criterio

  1. ¿El otro modelo es tuyo (de tu organización) y razonable?Lo publica otro equipo de BCPS Bank, con un esquema estable.
    conformista
  2. ¿Los dos equipos pueden negociar los cambios?Hay una relación de trabajo y prioridades compartidas.
    cliente-proveedor
  3. ¿Tienes muchos consumidores y no puedes adaptarte a cada uno?Como Cuentas con sus movimientos.
    OHS + lenguaje publicado
  4. ¿El otro modelo es ajeno, cambia sin avisar o es malo?Otro banco, un sistema antiguo, un proveedor.
    anti-corruption layer

El núcleo compartido va aparte: solo para piezas pequeñas, estables y que de verdad significan lo mismo en los dos lados, como un importe o un IBAN.

En el mundo real

Los tipos de relación vienen del libro de Evans (2003) y de su Domain-Driven Design Reference posterior. Hay más de los que salen aquí: partnership (dos equipos que triunfan o fracasan juntos), separate ways (no integrarse en absoluto) y el big ball of mud (reconocer una zona sin modelo claro y aislarla). La comunidad DDD Crew mantiene una chuleta de patrones de context mapping, y herramientas como Context Mapper permiten describir el mapa como código y generar los diagramas.

Las ACL más habituales en banca no son contra otros bancos (aunque esas existen, como adaptadores para cada red de pagos), sino contra el sistema antiguo del propio banco: el núcleo en mainframe que lleva décadas funcionando. La red de tarjetas es otro caso claro: sus mensajes tienen su propio formato y sus propios códigos de respuesta, y ningún banco quiere esos códigos repartidos por su modelo. Sam Newman describe la ACL como pieza del patrón strangler fig para ir sustituyendo un sistema antiguo poco a poco.

La distinción entre eventos de dominio y de integración aparece, con esos nombres, en la guía de microservicios de Microsoft (.NET) y en buena parte de la literatura de DDD con eventos.

Siguiente episodio

Hemos bajado del banco entero a los contextos, y de los contextos a sus relaciones. Queda un nivel más: dentro de Cuentas, ¿qué cosas tienen que cambiar juntas, en una sola transacción? En Black Friday, a Ana le llegan a la vez un pago con tarjeta, la nómina y el recibo de la luz. ¿Tienen que esperarse unos a otros?

Siguiente · Episodio 4 Agregados como frontera de consistencia Un agregado grande o varios pequeños, la contención en Black Friday, y la transferencia interna que rompe la regla a propósito.

← Todos los episodios · Mapa de BCPS Bank