Módulo 8: Proyecto — modernizar una rebanada de Mercado
Presentación del capstone: siete técnicas, un método
Por qué este módulo existe aquí
Llegaste al final de la guía, y este módulo es distinto de todos los anteriores. Los siete módulos previos te enseñaron una técnica cada uno: por qué no reescribir (M1), caracterizar el legacy (M2), el strangler fig (M3), branch by abstraction (M4), extraer un servicio (M5), migrar datos sin downtime (M6), medir el progreso (M7). Cada uno fue completo en sí mismo, con su propio proyecto. Y sin embargo, ninguno te enseñó lo más difícil —y lo único que de verdad importa cuando modernizas un sistema real—: usar las siete juntas, en orden, sobre una misma pieza, de principio a fin, hasta apagar el legacy.
Ese es el trabajo de este capstone, y fíjate en lo que no es: no es una octava técnica. No vas a aprender un patrón nuevo. Todo lo que necesitas ya lo tienes. Lo que agrega este módulo es el método —la forma de encadenar las siete técnicas en una sola modernización— y la experiencia de verlas trabajar juntas sobre una rebanada real del monolito de Mercado: el catalog. Vas a llevarlo desde donde empezó —una función interna del monolito legacy, sin tests, que nadie se atreve a tocar— hasta donde termina— un servicio autosuficiente, con su modelo limpio, sus datos propios, y el legacy borrado—, pasando por cada fase del arco, y midiendo cada afirmación con un número que sale de correr el código.
Recuerda el caso, que es el mismo de toda la guía: Mercado es un monolito legacy con catalog, orders, payments y shipping viviendo en un solo código, sobre una sola base de datos, sin tests, con partes que nadie quiere tocar. No lo reescribimos —esa fue la lección del módulo 1—. Lo modernizamos por rebanadas, y en este capstone llevamos la primera rebanada, catalog, de punta a punta. Cuando termines, no tendrás siete herramientas sueltas en una caja: tendrás un método que puedes aplicar a la siguiente rebanada —payments, shipping, orders— hasta que el monolito de Mercado desaparezca del todo.
Conexión con el módulo. Esta es la lección-mapa del capstone, y su trabajo es doble: hacer el recorrido de vuelta por M1-M7 —releerlos no como siete temas sino como los seis pasos de un solo método— y darte un teaser ejecutado del sistema modernizado corriendo end-to-end en miniatura, para que veas la película completa antes de rodarla escena por escena. La lección 2 elige y caracteriza la rebanada (M1 + M2); la 3 la pone tras el facade (M3); la 4 la extrae con un ACL (M5); la 5 migra sus datos (M6); la 6 mide el progreso (M7); la 7 declara el done y apaga el legacy (M7); y la 8 es el entregable, con la solución de referencia completa y el cierre de toda la guía. Fíjate en la frontera del capstone: aquí integramos la técnica de modernización de punta a punta. A dónde llega el catalog extraído (microservicio, eventos, API), la decisión de modernizar (el ADR), y las migraciones de datos a escala pertenecen a las guías hermanas —la lección 8 te dice cuáles y en qué orden seguir—.
Una analogía: el ascenso completo a la montaña
Piensa en aprender a escalar una montaña grande. No empiezas el primer día en la cumbre; entrenas por campamentos. Un fin de semana aprendes a leer el mapa y a decidir la ruta —no subir a lo loco—. Otro, a asegurar la cuerda antes de moverte. Otro, a instalar el campamento base. Otro, a cruzar un glaciar con crampones. Otro, a montar las cuerdas fijas en la pared. Otro, a leer el altímetro y el clima para saber si avanzas y cuándo dar la vuelta. Cada fin de semana dominaste una habilidad, en aislamiento, en terreno controlado.
Los siete módulos de esta guía fueron esos campamentos de entrenamiento. Decidir no reescribir fue aprender a leer el mapa y elegir la ruta (M1). Caracterizar el legacy fue asegurar la cuerda antes de moverte (M2). El strangler fig fue instalar el campamento base con una vía de retirada (M3). Branch by abstraction fue cruzar el glaciar por dentro (M4). Extraer el servicio fue montar las cuerdas fijas en la pared (M5). Migrar los datos fue subir la carga sin que se caiga (M6). Y medir el progreso fue leer el altímetro para saber si de verdad subes y cuándo llegaste (M7). Siete habilidades, cada una practicada por separado.
Pero saber cada habilidad no es haber hecho la cumbre. La cumbre es encadenarlas todas, en el orden correcto, en un solo ascenso continuo, con el cansancio real, el clima real, y la montaña real debajo. Es donde descubres que las habilidades no se usan una a una en cajones separados: se sostienen entre sí —la cuerda que aseguraste en el campamento 2 es la que te salva en la pared del campamento 5; el altímetro del campamento 6 es lo que te dice que la vía del campamento 3 está funcionando—. Este capstone es tu cumbre. Vas a encadenar las siete técnicas en un solo ascenso —modernizar el catalog de Mercado— y vas a ver cómo se sostienen unas a otras. El golden master que congelas en el paso 1 es exactamente lo que te deja implementar bien el descuento por volumen en el paso 5; el ACL que pones en el paso 3 es lo que hace que la migración de datos del paso 4 no rompa al monolito. Ninguna habilidad vive sola en la cumbre.
Ejemplo trabajado: el método completo, en miniatura
No vamos a describir el método: lo vamos a ejecutar, aunque sea en su versión más pequeña, las seis fases juntas en una tabla. La idea es ver la película entera antes de rodarla escena por escena —que tengas en la cabeza, desde ya, la forma completa del ascenso—. Cada fila es una técnica de M1-M7 aplicada al catalog de Mercado, y la columna medida es su número clave: el que dice, sin opinión, que esa fase hizo su trabajo.
# El metodo completo, una fila por fase, en miniatura.
# Cada fila es una tecnica de M1-M7; la columna "medida" es su numero clave.
fases = [
("M2", "caracterizar", "golden master fija el comportamiento", "6 casos en verde"),
("M3", "facade", "strangler router desvia trafico 0->100", "fallback 100 (bulk abierto)"),
("M5", "extraer", "ACL traduce viejo<->nuevo", "round-trip: True"),
("M6", "migrar datos", "parallel_run compara y reconcilia", "discrepancias 2 -> 0"),
("M7", "medir", "burn-down de legacy_calls", "1000 -> 0 (bulk migrado)"),
("M7", "done", "criterio duro: borrar el legacy", "done = True"),
]
print("El metodo completo, ejecutado en miniatura sobre el catalog de Mercado\n")
print(f"{'de':>3} {'paso':<14}{'que hace':<40}{'medida'}")
print("-" * 92)
for origen, paso, que, medida in fases:
print(f"{origen:>3} {paso:<14}{que:<40}{medida}")
print("-" * 92)
print("\n Seis pasos, no seis temas: la misma rebanada (catalog) atravesando todo el")
print(" arco, de 'funcion legacy que nadie toca' a 'servicio con el legacy borrado'.")
print(" Cada 'medida' es un numero que sale de correr el codigo, no de afirmarlo.")
Qué esperar. Al correr el archivo, la salida es exactamente esta:
El metodo completo, ejecutado en miniatura sobre el catalog de Mercado
de paso que hace medida
--------------------------------------------------------------------------------------------
M2 caracterizar golden master fija el comportamiento 6 casos en verde
M3 facade strangler router desvia trafico 0->100 fallback 100 (bulk abierto)
M5 extraer ACL traduce viejo<->nuevo round-trip: True
M6 migrar datos parallel_run compara y reconcilia discrepancias 2 -> 0
M7 medir burn-down de legacy_calls 1000 -> 0 (bulk migrado)
M7 done criterio duro: borrar el legacy done = True
--------------------------------------------------------------------------------------------
Seis pasos, no seis temas: la misma rebanada (catalog) atravesando todo el
arco, de 'funcion legacy que nadie toca' a 'servicio con el legacy borrado'.
Cada 'medida' es un numero que sale de correr el codigo, no de afirmarlo.
Lee la tabla de arriba hacia abajo, porque es el guion del capstone entero: cada fila es una lección de las que siguen, y las flechas te dicen adónde va cada número.
Caracterizar (M2). Antes de tocar el catalog, se congela su comportamiento actual en un golden master: 6 casos de precio, todos en verde. Esto no es opcional ni ceremonial —es la red de seguridad—: cualquier cosa que hagamos después se compara contra estos 6 números, y si alguno cambia sin querer, lo atrapamos antes de que llegue a un cliente. Fíjate en un detalle que reaparecerá: el golden master incluye las rarezas del legacy (un descuento por volumen que redondea de forma extraña), no solo lo "bonito".
Facade (M3). Se pone un strangler router delante del catalog y se desvía el tráfico de 0 a 100. Pero la medida dice fallback 100 (bulk abierto): a 100% de tráfico enrutado al nuevo, todavía 100 requests caen al legacy por fallback —las compras por volumen, que el modern aún no sabe calcular—. Esta es la primera pista de que "el tráfico está en el nuevo" no es "terminado".
Extraer (M5). Se saca el catalog a su propio servicio con un ACL que traduce el modelo viejo al limpio y de vuelta. La medida round-trip: True dice que el traductor es fiel: el monolito recibe exactamente lo que recibía, aunque por dentro ahora hay un servicio con otro modelo.
Migrar datos (M6). Se mueven los datos del catalog al store propio del servicio. El parallel-run compara viejo vs nuevo y encuentra discrepancias 2 -> 0: dos filas mal migradas, reconciliadas hasta cero. Solo con ese cero se cambian las lecturas al nuevo.
Medir (M7). El burn-down de llamadas al legacy baja de 1000 -> 0. Y aquí se cierra el círculo con el paso 1: el último tramo terco del burn-down —las 100 llamadas del descuento por volumen— solo llega a cero cuando el modern implementa el bulk pricing guiado por el golden master que congelamos en la fase de caracterizar. La red de seguridad del principio es la que permite terminar.
Done (M7). El criterio duro se cumple —done = True— y el legacy se borra. No "se apaga por si acaso": se borra. La rebanada quedó modernizada de punta a punta.
Esta tabla es el capstone en seis renglones. Las lecciones que siguen los ejecutan uno por uno, con su código completo y su salida literal. Guárdala en la cabeza como el mapa del ascenso.
El método: los seis pasos y cómo se sostienen
Ese teaser mostró las seis fases sin desarrollarlas. Vale la pena ver el orden y —sobre todo— las dependencias entre ellas, porque el método no es una lista de pasos independientes: es una cadena donde cada eslabón se apoya en los anteriores.
Paso Leccion De Que produce para el siguiente
────────────────────── ──────── ────────── ──────────────────────────────────
1. Caracterizar L2 M1 + M2 el golden master (la red de seguridad)
2. Poner tras el facade L3 M3 el trafico desviado, el fallback como detector
3. Extraer con ACL L4 M5 el servicio con modelo y datos propios
4. Migrar los datos L5 M6 el store nuevo verificado (discrepancias=0)
5. Medir el progreso L6 M7 el burn-down y la fitness function
6. Declarar el done L7 M7 el legacy borrado, la rebanada cerrada
Y así se sostienen entre sí, que es lo que un capstone revela y una lección aislada no puede:
flowchart LR
C["1. caracterizar<br/>(golden master)"] --> F["2. facade<br/>(strangler + fallback)"]
F --> E["3. extraer<br/>(ACL)"]
E --> D["4. migrar datos<br/>(parallel-run)"]
D --> M["5. medir<br/>(burn-down)"]
M --> DONE["6. done<br/>(borrar el legacy)"]
C -.el golden master guia el bulk.-> M
E -.el ACL protege al monolito.-> D
Lee las flechas punteadas, porque son el corazón del método. La flecha de caracterizar a medir dice que el golden master del paso 1 es lo que permite cerrar el burn-down en el paso 5: sin él, el modern no sabría reproducir el descuento por volumen con su rareza exacta, y las 100 llamadas de fallback nunca llegarían a cero. La flecha de extraer a migrar datos dice que el ACL del paso 3 es lo que hace segura la migración del paso 4: es el traductor que mantiene al monolito idéntico mientras los datos se mudan por debajo. Ninguna técnica es una isla. Ese entramado —no las técnicas sueltas— es lo que aprendes a manejar en el capstone.
El mapa: dónde está este módulo, y hacia dónde sigues
Este es el último módulo de la guía, así que su mapa mira en dos direcciones: hacia atrás, a todo lo que integra, y hacia afuera, a las guías hermanas donde sigues después de cerrar la migración.
flowchart TD
M1["M1 · No reescribir"]
M2["M2 · Caracterizar"]
M3["M3 · Strangler fig"]
M4["M4 · Branch by abstraction"]
M5["M5 · Extraer un servicio"]
M6["M6 · Migrar datos"]
M7["M7 · Medir el progreso"]
M8["M8 · CAPSTONE<br/>(el método completo)"]
M1 --> M2 --> M3 --> M4 --> M5 --> M6 --> M7 --> M8
El capstone se para sobre los siete y los integra. Y desde aquí, con la rebanada modernizada en las manos, las guías hermanas del ecosistema toman la posta: architecture-decisions-and-tradeoffs para registrar la decisión de modernizar (el ADR) y la reversibilidad como propiedad de diseño; architectural-styles-and-boundaries, event-driven-architecture y system-design-fundamentals para diseñar a dónde llega el servicio extraído (el estilo destino); y el ecosistema Data Engineering para las migraciones de datos a escala real —CDC, pipelines de billones de filas—. La lección 8 cierra la guía enlazando cada una en el orden que tiene sentido. Aquí, en M8, terminas de aprender la técnica; allá aprendes qué construir con ella.
Errores comunes
Tratar el capstone como "repasar las siete lecciones". Qué pasa: el alumno llega al módulo 8 y lo lee como un resumen —"ya vi esto"— sin ejecutar la cadena completa sobre una misma pieza. Por qué pasa: cada técnica ya se practicó, así que el capstone se siente redundante. Cómo detectarlo: si puedes recitar las siete técnicas pero no puedes decir, sin ver el código, en qué paso el golden master vuelve a aparecer y por qué, no integraste el método —memorizaste una lista—. Cómo corregirlo: el valor del capstone no está en las técnicas (esas ya las sabes) sino en las costuras entre ellas —cómo la salida de una es la entrada de la otra, cómo el fallback del paso 2 se vuelve el burn-down del paso 5, cómo el golden master del paso 1 cierra el paso 5—. Corre la cadena entera sobre el catalog y observa las costuras; ahí está lo que una lección aislada no te podía enseñar.
Creer que el orden de los pasos es arbitrario. Qué pasa: el equipo decide extraer el servicio (paso 3) antes de caracterizarlo (paso 1), o migrar los datos (paso 4) antes de poner el ACL (paso 3), porque "el orden da igual, al final se hace todo". Por qué pasa: los seis pasos parecen piezas independientes que se pueden barajar. Cómo detectarlo: la migración de datos rompe al monolito (porque no había ACL que lo protegiera), o una reimplementación cambia el comportamiento sin que nadie lo note (porque no había golden master). Cómo corregirlo: el orden es el método, y las flechas punteadas del mapa dicen por qué. Caracterizar va primero porque es la red que atrapa las regresiones de todo lo demás. El ACL va antes de migrar los datos porque es lo que mantiene al monolito idéntico durante la mudanza. Medir va al final porque solo tiene sentido medir un movimiento que ya está en marcha. Barajar los pasos no es "hacer lo mismo en otro orden": es quitarle a cada paso la red que los anteriores le ponían.
Confundir "las técnicas funcionaron" con "la rebanada está modernizada". Qué pasa: el equipo ejecuta las seis técnicas, cada una "sale bien", y declara la modernización terminada —pero el legacy sigue prendido, el fallback sigue en 100, o las lecturas nunca se cambiaron al nuevo—. Por qué pasa: seis técnicas ejecutadas se siente como seis logros, y "terminado" suena a "hice todo lo de la lista". Cómo detectarlo: pregunta "¿se borró el legacy del catalog?". Si la respuesta es "no, sigue ahí por si acaso" o "el tráfico ya está en el nuevo pero el viejo sigue", la rebanada no está modernizada. Cómo corregirlo: el capstone termina en un número, no en una lista de actividades: done = True con el legacy borrado. Ejecutar las técnicas es el medio; el fin es la rebanada cerrada y el legacy retirado. La lección 7 pone el criterio duro que distingue una cosa de la otra.
Ejercicios
Ejercicio 1 — De técnica a paso. Empareja cada módulo de la guía con el paso del método que le corresponde en el capstone, y di qué produce ese paso para el siguiente: (a) M2 (caracterizar), (b) M3 (strangler fig), (c) M5 (extraer), (d) M6 (migrar datos), (e) M7 (medir y done).
Ver solución
- (a) M2 → paso 1, caracterizar. Produce el golden master: la red de seguridad que congela el comportamiento actual del
catalogy atrapa cualquier regresión de todos los pasos siguientes. - (b) M3 → paso 2, poner tras el facade. Produce el tráfico desviado (por porcentaje, con fallback) y —clave— el fallback como detector: cada request que cae en fallback es una prueba de que el modern todavía tiene un hueco.
- (c) M5 → paso 3, extraer con ACL. Produce el servicio con modelo y datos propios, y el ACL que traduce viejo↔nuevo y mantiene al monolito idéntico —lo que hace segura la migración de datos del paso siguiente—.
- (d) M6 → paso 4, migrar los datos. Produce el store nuevo verificado: los datos mudados y confirmados con el parallel-run a discrepancias=0, listos para el read-switch.
- (e) M7 → pasos 5 y 6, medir y done. Produce el burn-down (cuánto falta), la fitness function (que el legacy no crezca) y el criterio de done (cuándo borrar el legacy). Es lo que declara la rebanada cerrada.
La idea de fondo: el método no es "aplicar seis técnicas", es una cadena donde cada eslabón entrega algo concreto al siguiente. Ver esas entregas es entender el método.
Ejercicio 2 — Las costuras. El texto insiste en que un capstone revela las costuras entre técnicas. (a) ¿Qué produce el paso 1 (caracterizar) que el paso 5 (medir) necesita para cerrar el burn-down? (b) ¿Qué produce el paso 3 (extraer con ACL) que el paso 4 (migrar datos) necesita para no romper al monolito? (c) ¿Por qué estas dependencias no se ven cuando estudias las técnicas por separado?
Ver solución
(a) El paso 1 produce el golden master del descuento por volumen —con su rareza de redondeo incluida—. El paso 5 lo necesita porque el burn-down solo llega a cero cuando el modern implementa el bulk pricing, y para implementarlo correctamente (reproduciendo el comportamiento exacto que produccion ya tiene, rareza incluida) el modern se guía por el golden master. Sin él, el modern calcularía un "5% limpio" que difiere del legacy, el fallback nunca cerraría, y el burn-down se quedaría atascado en 100.
(b) El paso 3 produce el ACL —el traductor viejo↔nuevo— y con él la garantía de que el monolito recibe siempre su modelo viejo exacto. El paso 4 lo necesita porque durante la migración de datos la fuente cambia por debajo (de shared_db a owned_db), y es el ACL de vuelta el que absorbe ese cambio y le sigue entregando al monolito lo de siempre. Sin el ACL puesto primero, mover los datos rompería el contrato del monolito.
(c) Porque cuando estudias una técnica aislada, su entrada y su salida son ejemplos de juguete auto-contenidos: el módulo 2 caracteriza algo, el módulo 7 mide algo, pero no el mismo algo encadenado. Las costuras solo aparecen cuando corres la cadena completa sobre una misma pieza, y la salida real de un paso se convierte en la entrada real del siguiente. El capstone existe justamente para hacer visible ese entramado que las lecciones sueltas no pueden mostrar.
Ejercicio 3 — Qué es y qué no es el capstone. Para cada afirmación, di si describe correctamente el capstone o no, y por qué: (a) "el módulo 8 enseña una octava técnica de migración"; (b) "el orden de los seis pasos se puede barajar sin consecuencias"; (c) "el capstone termina cuando las seis técnicas se ejecutaron"; (d) "el capstone integra M1-M7 sobre una misma rebanada y termina con el legacy borrado".
Ver solución
- (a) Incorrecta. El capstone no introduce ninguna técnica nueva —lo dice explícitamente—. Integra las siete que ya aprendiste; su aporte es el método de encadenarlas, no un octavo patrón.
- (b) Incorrecta. El orden es el método. Caracterizar va primero (la red de seguridad), el ACL antes de migrar los datos (para no romper al monolito), medir al final (solo se mide un movimiento en marcha). Barajar los pasos les quita a unos la red que los otros les ponían.
- (c) Incorrecta. Ejecutar las seis técnicas es el medio, no el fin. El capstone termina en un número medido —
done = Truecon el legacy borrado—, no en "hice todo lo de la lista". Se pueden ejecutar las seis y seguir con el legacy prendido y el fallback abierto. - (d) Correcta. Esa es exactamente la definición: M1-M7 integrados en orden sobre una misma rebanada (
catalog), midiendo cada paso, hasta que el criterio de done se cumple y el legacy se retira.
Resumen y siguiente paso
En esta lección instalaste la forma del capstone: releíste M1-M7 no como siete técnicas sueltas sino como los seis pasos de un solo método de modernización por rebanadas —caracterizar, poner tras el facade, extraer con ACL, migrar los datos, medir el progreso, declarar el done—, y viste, con la metáfora del ascenso completo a la montaña, que la cumbre no es saber cada habilidad por separado sino encadenarlas todas en un solo ascenso donde se sostienen entre sí. Y lo ejecutaste en miniatura: las seis fases en una tabla, cada una con su medida —golden master en verde, fallback 100, round-trip True, discrepancias 2→0, burn-down 1000→0, done True—, con las costuras a la vista (el golden master del paso 1 cerrando el burn-down del paso 5, el ACL del paso 3 protegiendo la migración del paso 4).
Antes de avanzar deberías poder: nombrar los seis pasos del método y qué produce cada uno para el siguiente; explicar por qué el orden no es arbitrario; identificar al menos dos costuras entre técnicas; y distinguir "las técnicas funcionaron" de "la rebanada está modernizada".
La lección 2 empieza el ascenso de verdad, por el primer paso: elegir y caracterizar la rebanada. Vas a ver por qué se moderniza catalog primero (la hoja del seam, del módulo 5) y —antes de tocar una línea— vas a ejecutar el characterization test que congela su comportamiento actual, rarezas incluidas, en un golden master, y a ver cómo atrapa la regresión cuando una reimplementación "limpia" cambia el número sin querer. El método empieza como debe: poniendo la red antes de subir.
Recursos
- Michael Feathers, Working Effectively with Legacy Code (Prentice Hall, 2004) — el libro que sostiene el primer paso del método: caracterizar antes de cambiar. El capstone empieza donde Feathers dice que hay que empezar —con la red de seguridad—, así que vale releer sus primeros capítulos con el arco completo en mente. En inglés.
- Martin Fowler, "StranglerFigApplication" (2004) — martinfowler.com/bliki/StranglerFigApplication.html. La metáfora que le da nombre a toda la guía: la higuera que envuelve al árbol y lo reemplaza sin talarlo de golpe. El capstone es esa metáfora ejecutada de principio a fin sobre una rebanada. En inglés.
- Sam Newman, Monolith to Microservices (O'Reilly, 2019) — la referencia integral de modernizar un monolito por partes: extraer servicios, migrar datos, y —clave para el capstone— hacerlo de forma incremental y medida. El libro que más se acerca a describir el método completo de este módulo. En inglés.
- Chris Richardson, "Microservice Architecture" — microservices.io. El catálogo de patrones de descomposición y migración; útil como índice para ver, desde arriba, cómo encajan las piezas que el capstone encadena. En inglés.