- El modelo C4 es un enfoque amigable para desarrolladores para crear diagramas de arquitectura de software, que permite ver estructuras complejas dividiéndolas por etapas.
- La abstracción desciende en el orden de software systems → containers → components → code, tratando la arquitectura de forma jerárquica.
- Los diagramas también se organizan siguiendo la estructura de system context → container → component → code.
- Según sea necesario, los diagramas de system landscape, dynamic y deployment complementan la estructura general y las perspectivas de ejecución y despliegue.
- Es un enfoque notation independent y tooling independent, por lo que puede aplicarse según el entorno existente sin quedar atado a una notación o herramienta específica.
Estructura del modelo C4
- El modelo C4 es un modelo para visualizar la arquitectura de software, y fue creado por Simon Brown.
- La idea central está en usar conjuntamente la abstracción jerárquica y los diagramas jerárquicos.
Diagramas e independencia
- Los diagramas principales están organizados para permitir ver la arquitectura con distintos niveles de profundidad.
- Los diagramas complementarios cubren perspectivas que la jerarquía principal por sí sola no alcanza a mostrar.
- El modelo es notation independent y tooling independent, así que no obliga a elegir una notación o herramienta específica.
- Como material relacionado, hay un video grabado en julio de 2019 en “Agile on the Beach 2019”, Visualising software architecture with the C4 model, y el material The C4 model.
1 comentarios
Comentarios de Hacker News
Creo que el mayor problema de los diagramas de arquitectura es que se desalinean con la base de código.
Este tipo de diagramas necesita generarse automáticamente. De lo contrario, el equipo no tiene forma de saber si la imagen que está viendo representa con precisión el estado más reciente del sistema.
Los diagramas muestran una perspectiva específica, resaltan ciertas características y omiten otras. Incluso para el mismo objeto, puede haber varios diagramas que expliquen distintos aspectos o escenarios. Al final, igual que los documentos de texto, los diagramas no tienen otra opción que mantenerse junto con el código y la arquitectura de la aplicación como parte habitual de la gestión de cambios.
En muchos proyectos, el código no está organizado de la misma forma que el modelo mental, y casi ningún lenguaje ofrece una manera de resolverlo. Marcarlo con comentarios en el código tiene el mismo problema que mantener actualizados los diagramas, los comentarios y la documentación.
Representan el estado objetivo, no el estado actual. El código debe seguir al diagrama, no al revés. El único caso en que tiene sentido generar diagramas desde el código es para ayudar a alguien que se incorpora a un proyecto sin documentación; incluso entonces, sería más bien generarlo una vez, limpiarlo para quitar ruido y usarlo después como documento de referencia.
Los diagramas de alto nivel deberían poder crearse rápido y desecharse rápido, y es tan importante lo que muestran como lo que omiten.
Me gusta C4. Antes pensaba que diagramas de contexto como “User -{do their job}-> System-of-Record” eran inútiles, pero ahora entiendo por qué.
Estoy trabajando con C4 en un nuevo diseño de un sistema complejo junto con equipos de escalamiento. Esta vez, al dibujar el diagrama de nivel superior, me di cuenta de que además de la UI web había una app móvil que podía quedar medio desconectada, así que ciertos comportamientos debían degradarse con elegancia cuando estuviera offline o cuando el backend fuera lento y todavía no hubiera ciertos resultados. Eso en el siguiente nivel llevó a una cola de trabajo, y luego otra vez al UX, lo que permitió decir con claridad qué solicitudes podían tardar indefinidamente en completarse. Seguramente habríamos llegado a eso tarde o temprano, pero el análisis puso el problema de frente. Todo porque hubo que dibujar un esquema de “Remote-User --{Mobile Stuff}--> Backend”. La herramienta da igual; por ejemplo, yo uso draw.io con pestañas por capa. Cuando se vuelva más específico, pienso separar las capas inferiores en archivos aparte.
Entiendo el argumento de que no hace falta un sistema formalizado para los diagramas, pero me parece que C4 es bastante liviano. Yo no bajo hasta el nivel de código.
Aun así, structurizr, que genera diagramas C4, me ha subido mucho la productividad. El enfoque de generar vistas con distintos niveles de detalle a partir de un solo modelo es excelente comparado con mermaid o plantuml, donde cada diagrama tiene que definir y redefinir de forma independiente los mismos componentes una y otra vez. El flujo de sacar una rama, modificar el modelo y presentar la idea me funcionó muy bien.
No había forma de dibujar conceptos que no encajaran estrictamente en C4. Por ejemplo, quería poner dos componentes dentro de una sola caja para expresar que actualmente se despliegan como un solo servicio, y no se podía. No significa que fuera un gran diseño en términos absolutos, pero habría ayudado al equipo a entenderlo. La idea de describir formalmente la arquitectura es buena, pero la falta de personalización en la salida de los diagramas fue demasiado pesada.
Describes la arquitectura y structurizr renderiza el diagrama.
Se puede hacer, pero es bastante engorroso, y cuando las descripciones de las flechas entre cajas se alargan, el auto-layout se descompone muy rápido.
Suelo considerar que la arquitectura de software es un conjunto de decisiones de diseño que guía la implementación.
Según mi experiencia, la mayoría de los arquitectos de software les dan lineamientos y estructura a los ingenieros de software. Pero la explicación de C4, cuando dice “crear un mapa del código existente en varios niveles de detalle”, suena distinto. No entiendo por qué a un diagrama de código se le llamaría arquitectura de software. Eso es literalmente nivel de código, así que cuesta verlo como arquitectura. Es como querer meter el diagrama del cableado de un enchufe en los planos de una casa. Si “hay que usar herramientas de automatización”, ¿entonces la idea es documentar una base de código existente a nivel de funciones? No veo cómo eso sería útil para diseñar y planificar software. Un mapa que describa la estructura de un software existente puede verse bien, pero cuando se habla de patrones de diseño, nadie entrega un mapa función por función de una implementación Singleton. Basta con decir que se necesita un Singleton o un patrón Repository. El diseño de software como tal claramente existe, y este enfoque también parece válido para el diseño, pero en mi experiencia diseño de software, implementación y arquitectura no son lo mismo, ni tampoco los hace la misma gente. Esto se ve más cercano al diseño de sistemas, y me imagino que el arquitecto de software tendría el rol de aconsejar para que ese diseño del sistema siga buenos principios de arquitectura. Tal vez me estoy poniendo demasiado quisquilloso
Creo que una función esencial de la arquitectura de software es dar información para que los desarrolladores puedan tomar decisiones de diseño por su cuenta, sin tener que escalar cada juicio a una autoridad. Aun así, varía mucho dónde termina la arquitectura y dónde empieza el desarrollo. Pienso que la propia arquitectura decide qué es importante desde una perspectiva arquitectónica. Si la arquitectura considera que cierto detalle de bajo nivel de la aplicación es importante, entonces eso también pasa a ser un detalle arquitectónico. En la práctica, en la mayoría de las organizaciones la arquitectura controla al menos el diseño de alto nivel, como componentes, patrones de comunicación, APIs y tecnologías usadas. En algunas organizaciones baja hasta clases individuales. No todas las clases, sino las que modelan el dominio del problema, especialmente cuando ese modelo se usa como lenguaje entre varios proyectos o se implementa como artefacto compartido. C4 encaja bien en organizaciones que consideran que la arquitectura también abarca estructuras de nivel más bajo, más allá de una lista de aplicaciones e interfaces de integración
En el fondo, se trata de tener diagramas para cada nivel que sea claramente distintivo o útil dentro del sistema. Si necesitas un diagrama a nivel de código, probablemente estás haciendo trabajo personalizado complejo, o estás especificando en exceso un diseño que podría dejarse como detalle de implementación
Se parece a cómo en la construcción real de inmuebles los roles de arquitecto, ingeniero y responsable de obra son distintos. Me pregunto dónde habría que poner la línea en arquitectura, diseño e implementación, y qué preocupaciones debería abordar cada una
Es interesante, pero no veo que aporte algo especialmente nuevo.
Los diagramas de alto nivel están bien, pero ya se pueden hacer sin necesidad de leer un sitio web elegante sobre modelos visuales. De hecho, el propio sitio prácticamente lo reconoce. Tiene mucha razón cuando dice que, aunque en la industria existen UML, ArchiMate y SysML, muchos equipos han optado por diagramas mucho más simples de “cajas y líneas”. Pero parece ignorar por qué los diagramas de clases UML fracasaron por completo. Aunque reconoce que a nadie le gustan, la cuarta C del modelo, código, termina siendo básicamente un diagrama de clases UML. Esto no hace falta. Solo hay que hacer diagramas arbitrarios de forma clara y poner etiquetas en las flechas. De hecho, los primeros tres diagramas son buenos ejemplos de eso
También ayuda mucho al pensar conceptos nuevos o hacer brainstorming, porque la herramienta no estorba. Ahora uso Freeform, que es muy simple pero funciona bien. Solo seleccionas dos objetos y haces cmd-clic o clic derecho, luego eliges “add connecting line”
Hace apenas unos meses terminé otro documento de arquitectura con suficientes diagramas de clases, diagramas de secuencia y casos de uso
Es muy fácil que las cajas terminen mezclando cosas de distintos niveles: algunas abstractas, otras concretas y otras simplemente arbitrarias. Entonces, por ejemplo, si tienes que encajar una pieza arquitectónica mayor como una cadena de suministro, en la práctica terminas rehaciendo casi todo. Hay mucho desperdicio, y como nadie tiene una visión suficientemente clara de toda la arquitectura, eso lleva a más desperdicio y a problemas de calidad. Curiosamente, muchos ingenieros reaccionan de forma defensiva ante enfoques más formales, probablemente porque no ven una ganancia inmediata o porque nunca han tenido que lidiar con arquitecturas a gran escala y no perciben el problema
Esto muestra que la ingeniería de software sigue siendo un campo inmaduro.
En mi caso, han pasado más de 25 años y seguimos teniendo prácticamente las mismas discusiones “básicas”. No es que eso sea malo, pero el progreso es lento, y tampoco se puede atribuir solo a una empresa concreta, un consorcio o intereses comerciales
¿Cuántas veces alguien ha estado cambiando dentro de una sola idea entre mucho detalle, mucha complejidad y una simplicidad vista desde lejos, haciendo difícil entender qué quiere decir? El mismo problema aparece cuando un desarrollador piensa “solo hay que dibujar unas cajas y flechas más o menos en esta pizarra; en mi cabeza tiene sentido, así que es un buen diagrama”
Aunque uno no sea ingeniero civil, puede entender de inmediato unos planos y sentir que son útiles.
Pero incluso siendo ingeniero de software profesional, estos diagramas de ejemplo no parecen lo bastante útiles ni informativos como para justificar el esfuerzo. El código es demasiado multidimensional como para aproximarlo bien en un dibujo 2D, y no termina de funcionar. Lo que sí podría tener potencial son patrones de código arquitectónico más estandarizados. Algo como la concurrencia estructurada, y quizá algo todavía de nivel más alto
Los planos de una casa tienen un contexto muy fijo y un alcance limitado. Por ejemplo, no hace falta explicar qué es una ventana. Pero en software casi siempre sí hay que explicar la “ventana” en sí. Como todas las “ventanas” o elementos son distintos entre sí, no puedes simplemente decir “esto es una ventana” y copiarlo 20 veces
Si el modelo C4 te parece demasiado arbitrario y excesivamente especificado, a inicios de este año escribí sobre una práctica alternativa: https://www.ilograph.com/blog/posts/concrete-diagramming-mod...
Me gusta este modelo, y también he tenido que usar UML en arquitectura de seguridad. Ahí la consistencia es clave, desde el contexto de más alto nivel hasta el código
La simplicidad del modelo C4 funciona como una especie de mecanismo de imposición. Si hay contexto o componentes ocultos, deberían quedar expuestos dentro del modelo. Si hay resistencia incluso a algo tan simple, lo veo como una señal de que puede haber elementos ocultos. En proyectos grandes, de hecho, normalmente los hay. Cuando haces que la gente aclare su pensamiento de esta manera, el poder se distribuye porque los obliga a comprometerse con afirmaciones e ideas, en lugar de solo dejarles el derecho de proponer y criticar. Eso también puede generar mucha resistencia. Pero no es un problema del modelo, sino de lo que pasa cuando el modelo se encuentra con las personas. Me gusta la consistencia, así que probablemente usaría este enfoque como referencia para diseño de seguridad
C4 me parece muy interesante y creo que aborda bien un problema específico de la arquitectura de software
Toma las capas bajas de la arquitectura —principalmente hardware y software de sistema— y las convierte en una abstracción amplia, para concentrar el esfuerzo en las cosas que están más arriba en la pila. Encaja sorprendentemente bien con el enfoque actual basado en nube, contenedorizado y escalable. En ese sentido, ArchiMate también es bueno y se superpone bastante, pero está más firmemente anclado en la infraestructura. En el pasado usé un enfoque de diagramas parecido a ArchiMate y me resultó muy efectivo para reducir choques entre sistemas y fuentes de datos, y para mostrar cómo las cosas que compramos e integramos apoyan requisitos específicos del negocio y de los flujos de trabajo de los usuarios. Es totalmente cierto que estas cosas se desalinean de la base de código. Pero al analizar sistemas complejos o al comunicar sistemas y planes a un grupo más grande, pueden ser herramientas excelentes. Sorprendentemente, muchas veces no existe ninguna documentación cohesionada, y simplemente sentarse unas semanas a dibujar cajas y líneas de conexión puede destrabar y simplificar trabajo frustrante que no lograba avanzar. Especialmente cuando varios equipos están trabajando en la misma área. C4, ArchiMate, UML y similares no son más que lenguajes de diagramación con restricciones que capturan cosas específicas que uno quiere comunicar, analizar y registrar. No creo que sean muy buenos como herramientas de planificación previa o de diseño. Mucha gente sufrió durante la gran moda de UML. Era esa idea de que, antes de escribir una sola línea de código, la organización de arquitectos principales tenía que detallar de forma dolorosamente minuciosa cada aspecto del sistema, hasta las definiciones de clases, y locuras como “ya luego generamos el código desde los diagramas” atormentaron a muchísima gente. Cuando el trabajo real de programación empezaba, por lo general esas miles de horas de planificación se ignoraban, y los desarrolladores terminaban haciendo lo que querían de todos modos.