Diagrama de Código C4 (nivel 4): cuándo lo necesitas y cuándo no
El diagrama de Código es el nivel más malentendido del modelo C4. Es el nivel que la mayoría de los equipos omite, el nivel que el propio Simon Brown describe como opcional, y aun así es también el nivel que genera más preguntas: "¿De verdad necesitamos dibujar nuestras clases?". "¿Esto no es simplemente UML?". "¿Quién mantiene esto cuando el código cambia?".
La respuesta corta: la mayoría de las veces, no necesitas un diagrama de Código C4. La respuesta larga es más interesante, porque los casos en los que el nivel 4 sí compensa son exactamente los casos en los que los equipos pierden más tiempo sin él -- algoritmos densos, dominios regulados y onboarding en código que ya nadie entiende del todo.
Esta guía cubre qué muestra realmente un diagrama de Código C4, por qué dibujar uno a mano es casi siempre un error, las situaciones específicas en las que el nivel 4 del modelo C4 vale la pena, y cómo la generación automática da la vuelta por completo al cálculo coste-beneficio.
Si el modelo C4 es nuevo para ti, empieza primero por nuestra guía completa del modelo C4 -- este artículo asume que conoces los cuatro niveles.
¿Qué es un diagrama de Código C4?
El diagrama de Código es el nivel 4 del modelo C4 -- el nivel de zoom más profundo. Donde el diagrama de Componentes (nivel 3) muestra las piezas principales dentro de un contenedor, el diagrama de Código hace zoom en un único componente y muestra sus detalles a nivel de implementación:
- Clases y sus relaciones (herencia, composición, dependencia)
- Interfaces y los tipos que las implementan
- Funciones y métodos, incluidas las firmas clave
- Estructuras de datos como entidades, objetos de valor y DTOs
En la práctica, un diagrama de nivel 4 de C4 suele renderizarse como un diagrama de clases UML o un diagrama entidad-relación. El modelo C4 no prescribe una notación para este nivel -- delega explícitamente en los estándares existentes porque el problema de dibujar clases se resolvió hace décadas.
Dos propiedades definen el nivel de Código:
- Alcance: un componente. Un diagrama de Código nunca abarca un contenedor entero, y mucho menos un sistema. Abre exactamente un componente -- el
OrderRepository, elPaymentService-- y muestra lo que hay dentro. - Granularidad: símbolos reales de código. Cada caja de un diagrama de Código se corresponde con una clase, interfaz o función real del código fuente. No queda ninguna abstracción. Este es el nivel donde se supone que el diagrama y el código son la misma cosa.
Esa segunda propiedad es precisamente la razón por la que el nivel 4 se omite tan a menudo, como veremos. (Para una referencia rápida, consulta la entrada de diagrama de código en nuestro glosario.)
La propia recomendación de Simon Brown: no lo dibujes
Aquí está la parte que sorprende a quienes se encuentran con el modelo C4 por primera vez: su creador recomienda no crear diagramas de Código a mano. La indicación de Simon Brown es que el nivel 4 es opcional, y cuando sí lo necesitas, debería generarse bajo demanda a partir del código fuente -- por tu IDE, por herramientas de documentación o por cualquier otra cosa que lea el código real -- en lugar de dibujarse y mantenerse a mano.
El razonamiento es difícil de rebatir:
- El código cambia constantemente. Un diagrama de clases dibujado a mano es preciso aproximadamente durante el tiempo que tarda alguien en mergear el siguiente pull request. Cada renombrado, cada método extraído, cada nuevo campo lo vuelve un poco más erróneo.
- La información ya existe. A diferencia de un diagrama de Contenedores -- que captura decisiones que no viven en la cabeza de nadie ni en un solo archivo -- un diagrama de Código duplica lo que el código fuente ya indica con precisión.
- Las herramientas lo hacen mejor. Los IDEs modernos (IntelliJ, Visual Studio y compañía) generan diagramas de clases a partir del código en segundos. Siempre son precisos porque son derivados, no dibujados.
Así que la posición por defecto de cualquier equipo que adopte C4 debería ser: modela los niveles 1-3, genera el nivel 4 cuando lo necesites. Los diagramas de Contexto, Contenedor y Componente capturan conocimiento que no está en el código. El nivel de Código es el código.
Cuándo un diagrama de Código C4 vale la pena de verdad
"Normalmente omítelo" no es "siempre omítelo". Hay situaciones reales en las que una vista a nivel de código se gana su lugar en tu documentación.
1. Algoritmos complejos y diseños intrincados
Algunos componentes implementan una lógica que es genuinamente difícil de seguir leyendo los archivos de arriba abajo: un motor de precios con estrategias encadenadas, una máquina de estados que gobierna los ciclos de vida de los pedidos, un parser con una jerarquía de visitantes profunda. Cuando la estructura del código es la clave -- cuando entender qué clase delega en cuál es toda la batalla -- un diagrama de Código comprime horas de lectura de código en una sola imagen.
La prueba: si un ingeniero senior necesita una pizarra para explicar el componente a otro ingeniero senior, ese boceto de pizarra es un diagrama de Código esperando a ser capturado.
2. Dominios regulados y auditados
En finanzas, sanidad, aviación y otras industrias reguladas, los auditores y evaluadores a menudo exigen documentación a nivel de implementación: qué clase maneja los datos del titular de la tarjeta, dónde se aplica el cifrado, cómo se escribe el rastro de auditoría. Aquí un diagrama de nivel 4 no es un "estaría bien tenerlo" -- es evidencia. Lo mismo aplica a las revisiones de seguridad y al modelado de amenazas, donde el flujo de datos a través de clases específicas importa.
3. Onboarding en código denso y de larga vida
Los componentes heredados con años de decisiones acumuladas son brutales para los recién llegados. Un diagrama de Código de los tres o cuatro componentes más aterradores de tu base de código -- aquellos donde se concentra el conocimiento tribal -- puede reducir drásticamente el tiempo de onboarding. Los nuevos desarrolladores ven la forma del componente antes de sumergirse en 8.000 líneas de él.
4. Documentar contratos públicos y patrones de diseño
Si un componente expone una superficie de API contra la que construyen otros equipos, o implementa un patrón (Strategy, Observer, puertos y adaptadores hexagonales) donde la estructura es la documentación, una vista a nivel de código hace explícito el contrato.
Cuándo no lo necesitas (que es la mayoría de las veces)
Sé honesto sobre los casos inversos, porque cubren la mayoría de los componentes de cualquier sistema:
- El código es legible. Un componente bien nombrado con paquetes claros no necesita un diagrama. El árbol de carpetas es el diagrama.
- El nivel 3 ya responde a la pregunta. Si alguien pregunta "¿cómo habla el servicio de pedidos con pagos?", esa es una pregunta de diagrama de Componentes. Dibujar clases añade ruido, no señal.
- El componente es un CRUD sencillo. Un handler, un service, un repository, un model. Todo el mundo ha visto esta forma mil veces. Documentarla a nivel de clase no documenta nada.
- Nadie lo pidió. La documentación debería responder a preguntas que la gente realmente tiene. Si nadie ha necesitado nunca una vista a nivel de clase de un componente, crear una es esfuerzo gastado en material de estantería.
El principio rector del enfoque C4 más amplio aplica aquí con toda su fuerza: cada diagrama que creas es un diagrama que debes mantener. En los niveles 1-3, el coste de mantenimiento te compra conocimiento que no existe en ningún otro sitio. En el nivel 4, normalmente te compra una copia ligeramente más bonita y ligeramente obsoleta de tu código fuente.
Cómo la generación automática cambia la ecuación
Todo lo anterior asume que alguien tiene que dibujar y mantener el diagrama. Esa suposición es lo que hacía que el consejo de Simon Brown de "omítelo o genéralo" fuera la decisión correcta -- el coste del nivel 4 manual casi nunca justificaba el beneficio.
La automatización elimina el lado del coste de esa ecuación. El descubrimiento por IA de Archyl analiza tu repositorio conectado y extrae elementos a nivel de código -- clases, interfaces y funciones -- directamente del código fuente, adjuntándolos a los componentes correctos de tu modelo C4. En lugar de un desarrollador dibujando PaymentService y sus colaboradores en una herramienta de diagramas, el modelo se rellena a partir de lo que existe de verdad en la base de código, y se mantiene conectado al repositorio del que procede.
Esto cambia la pregunta de "¿vale la pena mantener el nivel 4?" a "¿vale la pena tener el nivel 4?" -- un listón mucho más fácil de superar. Cuando la vista a nivel de código se genera y se refresca en lugar de dibujarse a mano:
- Nunca miente, porque se deriva del código fuente en lugar del recuerdo que alguien tiene del código fuente.
- Es navegable en contexto: profundizas de sistema a contenedor a componente a código en un solo modelo, en lugar de cazar un PNG en una wiki.
- Los casos que eran "valían la pena a pesar del coste" (auditorías, onboarding, componentes complejos) pasan a valer la pena de forma trivial, y los casos marginales pasan a ser gratis.
Sigues aplicando criterio sobre qué componentes merecen atención en el nivel 4 -- una vista generada de un componente CRUD trivial sigue siendo ruido. Pero el modo de fallo pasa de "un diagrama obsoleto induce a error al equipo" a "una vista sin usar que no cuesta nada".
Un ejemplo resuelto: dentro de un componente de procesamiento de pagos
Hagámoslo concreto. Supón que tu diagrama de Componentes (nivel 3) muestra un componente PaymentProcessor dentro de tu contenedor de API de backend. Hacer zoom en él en el nivel 4 podría revelar:
[PaymentService (interface)]
├── ProcessPayment(order, method) -> PaymentResult
└── RefundPayment(paymentID, amount) -> RefundResult
[StripePaymentService] ──implements──> [PaymentService]
[StripePaymentService] ──uses──> [StripeAdapter] : wraps the Stripe SDK
[StripePaymentService] ──uses──> [RetryPolicy] : exponential backoff, 3 attempts
[StripePaymentService] ──uses──> [PaymentRepository] : persists payment records
[StripeAdapter] ──maps──> [PaymentResult] : translates Stripe responses to domain types
[RetryPolicy] ──raises──> [PaymentFailedError] : after exhausting retries
[PaymentRepository] ──persists──> [Payment (entity)]
Fíjate en lo que responde esta vista que el nivel 3 no puede:
- ¿Dónde está la costura para las pruebas?
PaymentServicees una interfaz; las pruebas pueden sustituirla por un doble sin tocar Stripe. - ¿Dónde se enchufaría un segundo proveedor? Un
PaypalPaymentServiceque implemente la misma interfaz -- la estructura hace obvio el punto de extensión. - ¿Qué pasa en caso de fallo? La clase
RetryPolicyposee el comportamiento de backoff;PaymentFailedErrores la vía de escalado. Un auditor que pregunte "¿qué pasa cuando un cargo falla?" obtiene una respuesta del diagrama. - ¿Qué toca la base de datos? Solo
PaymentRepository. El flujo de datos del titular de la tarjeta es rastreable, lo cual importa enormemente en un componente dentro del alcance de PCI.
Este es un componente donde el nivel 4 se amortiza: es financieramente sensible, el manejo de fallos no es evidente y varias clases colaboran en un patrón deliberado. Contrástalo con, digamos, un UserProfileHandler que lee y escribe un registro de perfil -- dibujar eso a nivel de clase no te diría nada que el árbol de archivos no diga.
Errores comunes con el nivel 4 de C4
Mantener diagramas de clases a mano
El fallo clásico. Un ingeniero motivado dibuja preciosos diagramas de clases para toda la base de código; seis meses después describen una base de código que ya no existe, y ahora inducen a error de forma activa. Si un diagrama de Código no se genera a partir del código fuente -- o como mínimo se regenera de forma programada -- trátalo como caducado el día en que se dibuja.
Documentar getters, setters y código repetitivo
Un diagrama de Código que lista cada accesor, cada sobrecarga de constructor y cada método de utilidad tiene el mismo problema que un mapa a escala 1:1. Incluye los elementos que cargan intención de diseño -- interfaces, colaboraciones clave, los métodos que definen el contrato -- y omite la ceremonia. Las vistas generadas deberían filtrarse, no volcarse.
Usar el nivel 4 donde basta el nivel 3
Si tu "diagrama de código" muestra cosas como "el controller llama al service que llama al repository", has dibujado un diagrama de Componentes con cajas en forma de clase. Colápsalo de nuevo al nivel 3. Reserva el nivel 4 para componentes cuya estructura interna es la parte interesante.
Dibujar todo el contenedor a nivel de clase
Un diagrama de 200 clases que abarca un servicio entero viola la jerarquía de C4 y, de todos modos, es ilegible. Un diagrama de Código cubre un componente. Si no puedes acotarlo con tanta precisión, los límites de los componentes en tu diagrama de nivel 3 probablemente necesiten repensarse.
Tratar el nivel 4 como obligatorio para una documentación "completa"
Algunos equipos adoptan C4 con mentalidad de checklist: cuatro niveles, así que cuatro conjuntos de diagramas. El resultado es esfuerzo desperdiciado y resentimiento hacia toda la práctica. C4 es explícito en que el nivel 4 es opcional. Tres niveles bien mantenidos ganan a cuatro pudriéndose siempre.
Preguntas frecuentes
¿Es el nivel 4 de C4 simplemente un diagrama de clases UML?
En su mayoría, sí -- y eso es por diseño. El modelo C4 no define su propia notación para el nivel de Código; recomienda reutilizar las existentes, y un diagrama de clases UML es la opción más común (los diagramas ER funcionan para componentes centrados en datos). Lo que C4 añade es alcance y contexto: el diagrama de clases describe exactamente un componente, y ese componente se sitúa dentro de una jerarquía navegable de diagramas de contenedor y de sistema. Un diagrama de clases UML aislado flota libre; un diagrama de código C4 tiene una dirección.
¿Debería crear un diagrama de código para cada componente?
No. La mayoría de los componentes son lo bastante simples como para que el código fuente sea la mejor documentación. Reserva el nivel 4 para componentes que son algorítmicamente complejos, sensibles desde el punto de vista de seguridad o cumplimiento, o notorios obstáculos de onboarding. Si la documentación se genera automáticamente, el coste de tener más cobertura baja -- pero la atención sigue siendo finita, así que cura lo que expones.
¿Cómo mantengo un diagrama de código actualizado?
No manteniéndolo a mano. Genéralo: desde tu IDE bajo demanda, desde herramientas de documentación en CI, o desde una plataforma como Archyl que extrae clases, interfaces y funciones de tu repositorio durante el descubrimiento por IA y mantiene el nivel de código adjunto a tu modelo de componentes. Cualquier proceso que dependa de que un humano se acuerde de actualizar un diagrama de clases tras un refactor fracasará.
¿Cuál es la diferencia entre un componente y un elemento de código en C4?
Un componente (nivel 3) es una agrupación lógica con una única responsabilidad -- "la parte que maneja los pagos" -- y puede abarcar varias clases y archivos. Un elemento de código (nivel 4) es un símbolo real del código fuente: una clase, interfaz o función específica. Los componentes son abstracciones que tú eliges; los elementos de código son hechos que el compilador impone.
La conclusión
El diagrama de Código C4 es el nivel que deberías omitir por defecto y desplegar de forma deliberada. Los niveles 1-3 capturan conocimiento arquitectónico que no existe en ningún otro sitio; el nivel 4 refleja lo que el código ya dice, así que solo se gana un lugar cuando la propia estructura es la parte difícil -- algoritmos complejos, componentes regulados, código heredado denso -- e idealmente cuando se genera en lugar de dibujarse.
Si quieres vistas a nivel de código sin el impuesto de mantenimiento, conecta un repositorio a Archyl y deja que el descubrimiento por IA extraiga las clases, interfaces y funciones a tu modelo C4 automáticamente. Obtienes la profundidad cuando la necesitas, y nadie tiene que volver a redibujar un diagrama de clases nunca más.
¿Quieres subir un nivel? Lee la guía del diagrama de Componentes C4, repasa con la guía completa del modelo C4, o explora la visión general del modelo C4. ¿Listo para probarlo? Empieza con Archyl gratis.