Contextos delimitados y mapeo de contextos
Divida dominios grandes en contextos delimitados que se comuniquen de forma segura.
Contextos delimitados y mapeo de contextos es una lección gratuita de PHP Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de PHP Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de PHP Academy incluye 4 lecciones en total.
DDD estratégico
Los patrones tácticos modelan objetos dentro de un dominio; el DDD estratégico decide cómo dividir un sistema grande en partes que puedan evolucionar de forma independiente. El concepto central es el Contexto delimitado: un límite explícito dentro del cual un modelo de dominio y su lenguaje son coherentes. El Mapeo de contextos describe cómo se relacionan esos contextos. Esto suele tener más impacto que cualquier diseño de clase individual.
El lenguaje ubicuo
Dentro de un contexto delimitado, el equipo comparte un lenguaje ubicuo: los mismos términos que se utilizan en las conversaciones, el código y el modelo. Pero hay un detalle: una palabra puede significar cosas distintas en contextos diferentes. Un Cliente en Ventas (clientes potenciales, descuentos) no es lo mismo que un Cliente en Soporte (tickets, SLA). Un contexto delimitado hace explícito ese límite en lugar de imponer un único modelo compartido y sobredimensionado.
Una misma palabra, modelos distintos
El mismo concepto de negocio recibe un modelo específico del contexto. Un Product en Catálogo se ocupa de las descripciones y el contenido multimedia; en Inventario, de las existencias y la ubicación. Cada contexto define únicamente lo que necesita.
<?php
namespace Catalog;
final class Product {
public function __construct(
public readonly string $sku,
public readonly string $description
) {}
}
namespace Inventory;
final class Product {
public function __construct(
public readonly string $sku,
public readonly int $onHand
) {}
}
namespace App;
$c = new \Catalog\Product('A1', 'Blue mug');
$i = new \Inventory\Product('A1', 42);
echo $c->description, ' / ', $i->onHand, PHP_EOL;
Por qué no tener un único modelo grande
Intentar que un único Customer canónico sirva a todos los equipos produce una clase dios con requisitos contradictorios, fricción entre los equipos y cambios frágiles. Los contextos delimitados permiten que cada equipo sea dueño de su modelo y su lenguaje, despliegue de forma independiente y traduzca en los límites. El límite es el punto en el que se asume un pequeño coste de integración para evitar un gran coste de acoplamiento.
Mapas de contexto
Un Mapa de contexto es una representación de alto nivel de sus contextos delimitados y de las relaciones entre ellos. Registra tanto la integración técnica como la relación entre equipos y de poder (quién depende de quién y quién puede imponer cambios). DDD denomina varios patrones de relación recurrentes, que repasaremos a continuación.
Conformista en el código
Las relaciones suelen ser direccionales: un contexto ascendente influye en uno descendente (Cliente/Proveedor, Conformista, Capa anticorrupción). Un contexto descendente conformista no tiene capacidad de negociación, así que adopta tal cual el modelo del contexto ascendente: consume directamente la estructura ajena y acepta el acoplamiento.
<?php
// Upstream's shape, used verbatim downstream (Conformist)
final class UpstreamUser {
public function __construct(public readonly int $userId, public readonly string $login) {}
}
final class Greeter { // conforms: depends directly on upstream type
public function greet(UpstreamUser $u): string {
return "Hello {$u->login} (#{$u->userId})";
}
}
echo (new Greeter())->greet(new UpstreamUser(7, 'jane')), PHP_EOL;
Capa anticorrupción
Una ACL traduce un modelo externo o heredado al modelo limpio de su contexto para que los conceptos ajenos nunca se filtren hacia dentro. Es el patrón Adapter aplicado en el límite de un contexto, y protege su lenguaje ubicuo.
<?php
// Our clean domain model
final class Customer {
public function __construct(public readonly string $id, public readonly string $name) {}
}
// Legacy/external shape we must not let leak in
$legacy = ['CUST_NO' => '0042', 'FULL_NM' => 'Jane Doe'];
final class LegacyCustomerAcl {
public function toDomain(array $row): Customer {
return new Customer($row['CUST_NO'], $row['FULL_NM']);
}
}
$customer = (new LegacyCustomerAcl())->toDomain($legacy);
echo $customer->id, ' ', $customer->name, PHP_EOL;
Núcleo compartido en el código
- Núcleo compartido: dos contextos comparten un pequeño subconjunto del que son propietarios conjuntamente (más abajo, un tipo
Moneycomún); cámbienlo solo de común acuerdo. - Asociación: dos equipos triunfan o fracasan juntos.
- Caminos separados: la integración no compensa su coste.
- Servicio de anfitrión abierto / Lenguaje publicado: el contexto ascendente ofrece un protocolo estable y documentado para muchos consumidores.
<?php
namespace Shared; // small, jointly-owned kernel
final class Money {
public function __construct(public readonly int $cents, public readonly string $cur) {}
public function format(): string { return number_format($this->cents / 100, 2) . ' ' . $this->cur; }
}
namespace Billing; // depends on the shared kernel
use Shared\Money;
function invoiceTotal(): Money { return new Money(4999, 'USD'); }
namespace Payroll; // also depends on the SAME shared kernel
use Shared\Money;
function salary(): Money { return new Money(500000, 'USD'); }
Integración de contextos en PHP
En la práctica, los contextos se integran mediante contratos bien definidos: un método de traducción, un cliente de API que envuelve un Lenguaje publicado o mensajes. El lado receptor transforma el DTO ajeno en su propio modelo, de modo que el acoplamiento se detiene en el límite.
<?php
// Published Language DTO from an upstream Open Host Service
final class PricingDto {
public function __construct(public readonly string $sku, public readonly int $cents) {}
}
// Our downstream model
final class CatalogPrice {
public function __construct(public readonly string $sku, public readonly float $amount) {}
}
final class PricingTranslator {
public function translate(PricingDto $dto): CatalogPrice {
return new CatalogPrice($dto->sku, $dto->cents / 100);
}
}
$p = (new PricingTranslator())->translate(new PricingDto('A1', 1599));
echo $p->amount, PHP_EOL; // 15.99
Contextos y arquitectura
Los contextos delimitados se corresponden naturalmente con unidades de despliegue: un monolito modular con límites claros entre módulos o microservicios separados. El límite debe trazarse alrededor de la capacidad de negocio, no de las capas técnicas. Los microservicios que dividen un único contexto estrechamente acoplado crean un monolito distribuido; unos límites de contexto bien alineados producen servicios que cambian de forma independiente.
Los eventos como punto de integración
En la práctica, una forma limpia de integrar contextos sin compartir modelos consiste en intercambiar eventos. El contexto ascendente publica un evento pequeño y estable (un Lenguaje publicado); el contexto descendente se suscribe y lo transforma en su propio modelo, sin importar nunca las clases del contexto ascendente.
<?php
// Published Language: a minimal stable contract
final class OrderPlacedEvent {
public function __construct(public readonly string $orderId, public readonly int $cents) {}
}
// Downstream (Shipping context) maps it to its own model
final class Shipment {
public function __construct(public readonly string $forOrder) {}
}
final class ShippingListener {
public function on(OrderPlacedEvent $e): Shipment {
return new Shipment($e->orderId); // ignores fields it doesn't need
}
}
$shipment = (new ShippingListener())->on(new OrderPlacedEvent('o1', 1300));
echo 'shipment for ', $shipment->forOrder, PHP_EOL;
Comprobación rápida
Relaciones entre contextos.
Repaso
Ha pasado del DDD táctico al estratégico. Un Contexto delimitado es el límite dentro del cual un modelo y su lenguaje ubicuo mantienen la coherencia, lo que libera a los equipos de un único modelo compartido y sobredimensionado. Un Mapa de contexto documenta las relaciones —Cliente/Proveedor, Conformista, Capa anticorrupción, Núcleo compartido, Asociación, Caminos separados, Servicio de anfitrión abierto/Lenguaje publicado— y recoge tanto la integración técnica como la dinámica de los equipos. Trace los límites alrededor de las capacidades de negocio, traduzca en los extremos y su sistema podrá evolucionar en partes que se desplieguen de forma independiente.
Preguntas frecuentes
¿La lección «Contextos delimitados y mapeo de contextos» es gratis?
Sí — el texto completo de «Contextos delimitados y mapeo de contextos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de PHP Academy, actualiza a CoddyKit PRO. El curso de PHP Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Contextos delimitados y mapeo de contextos»?
Divida dominios grandes en contextos delimitados que se comuniquen de forma segura. Practicas PHP Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar PHP Academy?
No se requiere experiencia previa. PHP Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Contextos delimitados y mapeo de contextos»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de PHP Academy?
Sí. Cada lección de PHP Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Bloques de construcción de DDD: entidades y objetos de valor
- Agregados, repositorios y fábricas
- Eventos y servicios de dominio
- Contextos delimitados y mapeo de contextos