Diagrams-as-Code, Ingeniería Inversa y Arquitectura Moderna
El modelado de software ha evolucionado significativamente con las metodologías ágiles y DevOps. En lugar de crear diagramas pesados y estáticos en herramientas visuales cerradas que quedan desactualizados rápidamente, la industria actual adopta el paradigma Diagrams-as-Code (DaC) y técnicas de ingeniería directa e inversa.
En este tema aprenderás cómo integrar UML en repositorios Git, automatizar la generación de diagramas en CI/CD y modelar arquitecturas contemporáneas (microservicios, eventos asíncronos y Domain-Driven Design).
1. El Paradigma Diagrams-as-Code (DaC) #
Diagrams-as-Code consiste en escribir la arquitectura y el diseño de un sistema en texto plano estructurado que se compila a imágenes vectoriales (SVG/PNG) o se renderiza dinámicamente en navegadores.
Ventajas Clave #
- Control de versiones con Git: Permite hacer
git diff, revisiones en Pull Requests (Code Reviews) y trazabilidad de cambios en la arquitectura. - Documentación viva (Living Documentation): Los diagramas residen junto al código fuente en archivos Markdown (
README.md,docs/*.mdx) y se actualizan en el mismo commit que la lógica del sistema. - Automatización en CI/CD: Herramientas CLI compilan los diagramas automáticamente en pipelines de GitHub Actions o GitLab CI al fusionar cambios en la rama principal.
Herramientas Principales #
- PlantUML: El estándar industrial más maduro y completo para todos los diagramas UML 2.5.
- Mermaid.js: Renderizado nativo en Markdown soportado directamente por GitHub, GitLab, Notion y Obsidian.
- Structurizr / C4 Model: Modelado jerárquico de arquitectura (Contexto, Contenedores, Componentes y Código).
2. Ingeniería Directa e Inversa #
La ingeniería de software basada en modelos conecta el diseño con el código en dos direcciones:
1@startuml 2rectangle "Modelo UML\n(PlantUML / XMI)" as UML #E0F2FE 3rectangle "Código Fuente\n(Java / TS / Python)" as CODE #DCFCE7 4 5UML --> CODE : Ingeniería Directa (Generación de esqueletos/DTOs) 6CODE --> UML : Ingeniería Inversa (Reflexión / AST parsing) 7@enduml
Herramientas de Ingeniería Inversa Comunes #
| Lenguaje | Herramienta CLI | Comando / Uso |
|---|---|---|
| Python | pyreverse (incluido en Pylint) | pyreverse -o png -p MiProyecto src/ (genera diagramas de clases y paquetes). |
| Java | plantuml-maven-plugin / javadoc | Genera diagramas UML automáticamente al compilar con Maven/Gradle. |
| TypeScript | ts-uml / tsoa | Inspecciona el AST del compilador de TypeScript para extraer interfaces y clases. |
3. Modelado de Arquitecturas Modernas #
A. Microservicios y Mensajería Asíncrona (Event-Driven) #
En sistemas distribuidos, los diagramas de secuencia y componentes modelan tanto llamadas síncronas HTTP/gRPC como eventos asíncronos desacoplados mediante brokers (Kafka, RabbitMQ):
1@startuml 2participant "API Gateway" as GW 3participant "Servicio Pedidos" as ORD 4queue "Apache Kafka\n(Topic: pedidos.creados)" as KAFKA 5participant "Servicio Pagos" as PAY 6participant "Servicio Notificaciones" as NOTIF 7 8GW -> ORD : POST /api/v1/pedidos (síncrono REST) 9activate ORD 10ORD -> ORD : Guardar pedido en PostgreSQL 11ORD -> KAFKA : Publicar evento: PedidoCreadoEvent (asíncrono) 12ORD --> GW : 202 Accepted {id: "ped-101"} 13deactivate ORD 14 15KAFKA -> PAY : Consumir evento 16activate PAY 17PAY -> PAY : Procesar cobro con pasarela 18deactivate PAY 19 20KAFKA -> NOTIF : Consumir evento 21activate NOTIF 22NOTIF -> NOTIF : Enviar email de confirmación 23deactivate NOTIF 24@enduml
B. Domain-Driven Design (DDD) y Límites de Contexto #
UML se utiliza ampliamente para definir los límites de contexto (Bounded Contexts) y los agregados del dominio en el diseño estratégico y táctico:
1@startuml 2package "Bounded Context: Facturación" <<subdomain>> { 3 class Factura <<AggregateRoot>> { 4 -id: UUID 5 -fechaEmision: LocalDate 6 -estado: EstadoFactura 7 +calcularTotal(): Dinero 8 } 9 10 class LineaFactura <<Entity>> { 11 -concepto: String 12 -cantidad: Integer 13 -precioUnitario: Dinero 14 } 15 16 class Dinero <<ValueObject>> { 17 -cantidad: Decimal 18 -moneda: String 19 } 20 21 Factura "1" *-- "*" LineaFactura : contiene 22 LineaFactura o-- "1" Dinero : expresado en 23} 24@enduml
4. Buenas Prácticas de Modelado en Equipos Ágiles #
- Modelar para comunicar, no por burocracia: Un diagrama debe responder una pregunta concreta sobre el sistema (por ejemplo: "¿cómo se procesa una devolución?" o "¿qué dependencias tiene este microservicio?").
- Mantener los diagramas enfocados: Evita diagramas monolíticos con 50 clases. Es preferible tener 5 diagramas pequeños con 5 a 8 elementos cada uno que ilustren aspectos específicos.
- Versionar el texto fuente: Guarda siempre los archivos
.pumlo.mmden el repositorio junto a la documentación para que cualquier miembro del equipo pueda modificarlos fácilmente mediante un Pull Request.