- O modelo C4 é uma abordagem amigável para desenvolvedores para criar diagramas de arquitetura de software, permitindo visualizar estruturas complexas em etapas
- A abstração desce na ordem software systems → containers → components → code, tratando a arquitetura de forma hierárquica
- Os diagramas também são estruturados seguindo system context → container → component → code
- Conforme necessário, diagramas de system landscape, dynamic e deployment complementam a visão da estrutura geral e das perspectivas de execução e implantação
- Por ser uma abordagem notation independent e tooling independent, sem ficar presa a uma notação ou ferramenta específica, pode ser aplicada ao ambiente existente
Composição do modelo C4
- O modelo C4 é um modelo para visualizar arquitetura de software, criado por Simon Brown
- O ponto central está em usar em conjunto abstração hierárquica e diagramas hierárquicos
Diagramas e independência
- Os diagramas básicos são organizados para permitir ver a arquitetura em diferentes níveis de profundidade
- Os diagramas auxiliares complementam perspectivas que apenas as camadas básicas não cobrem suficientemente
- O modelo é notation independent e tooling independent, portanto não impõe uma notação específica nem a escolha de uma ferramenta
- Entre os materiais relacionados, há o vídeo Visualising software architecture with the C4 model, gravado em julho de 2019 no “Agile on the Beach 2019”, e o material The C4 model
1 comentários
Comentários do Hacker News
Acho que o maior problema dos diagramas de arquitetura é que eles acabam se desalinhando da base de código
Esses diagramas precisam ser gerados automaticamente. Caso contrário, a equipe não tem como saber se o desenho que está vendo representa com precisão o estado atual do sistema
Diagramas mostram uma perspectiva específica, destacando certas características e omitindo outras. Pode haver vários diagramas do mesmo objeto explicando diferentes aspectos ou cenários. No fim, diagramas também precisam ser mantidos junto com o código e com a arquitetura da aplicação, como documentos de texto, e não há muito além de tratá-los como uma tarefa regular de gerenciamento de mudanças
Em muitos projetos, o código não é organizado da mesma forma que o modelo mental, e quase nenhuma linguagem oferece uma forma de resolver isso. Marcar isso no código com comentários sofre do mesmo problema de manter diagramas, comentários e documentação atualizados
Eles representam o estado desejado, não o estado atual. O código deve seguir o diagrama, e não o contrário. Gerar diagramas a partir do código só faz sentido para ajudar quem acabou de entrar em um projeto sem documentação e, mesmo assim, a ideia seria gerar uma vez, limpar o ruído, refiná-los e depois usá-los como documento de referência
Diagramas de alto nível deveriam poder ser criados rápido e descartados rápido, e o que se omite é tão importante quanto o que se mostra
Gosto do C4. Antes eu achava inúteis diagramas de contexto como “User -{do their job}-> System-of-Record”, mas agora entendo o motivo
Estou conduzindo o novo design de um sistema complexo com equipes de expansão usando C4. Desta vez, ao desenhar o diagrama de mais alto nível, percebi que, além da UI web, existe um app móvel que pode ficar meio desconectado, então alguns comportamentos precisam degradar de forma elegante quando estiver offline ou quando o backend estiver lento e certos resultados ainda não existirem. Isso levou, no próximo nível, a uma fila de trabalho, e depois à UX, permitindo dizer com clareza que algumas requisições podem levar um tempo indefinido para serem concluídas. Eu teria chegado nisso em algum momento, mas a análise colocou esse problema bem na frente. Tudo porque foi preciso desenhar “Remote-User --{Mobile Stuff}--> Backend”. A ferramenta usada não importa; eu, por exemplo, separo as camadas em abas no draw.io. Quando ficar mais específico, pretendo separar os níveis mais baixos em arquivos diferentes
Entendo a opinião de que diagramas não precisam de um sistema formalizado, mas acho que o C4 é bem leve. Eu não desço até o nível de código
Ainda assim, o structurizr aumentou bastante minha produtividade ao gerar diagramas C4. A abordagem de gerar, a partir de um único modelo, visualizações com vários níveis de detalhe é excelente em comparação com mermaid, plantuml etc., em que cada diagrama precisa definir e redefinir repetidamente os mesmos componentes de forma independente. Para mim, o fluxo de criar uma branch, modificar o modelo e apresentar a ideia funcionou muito bem
Não havia como desenhar conceitos que não se encaixassem estritamente no C4. Por exemplo, eu queria colocar dois componentes dentro de uma caixa para representar o fato de que atualmente eles são implantados como um único serviço, mas isso não era possível. Isso não quer dizer que seja um design ideal em termos absolutos, mas teria ajudado a equipe a entender. A ideia de descrever arquitetura formalmente é boa, mas a falta de personalização na saída dos diagramas foi difícil de engolir
Você descreve a arquitetura e o structurizr renderiza os diagramas
Dá para fazer, mas é bastante incômodo, e quando as descrições das setas entre caixas ficam longas, o layout automático desmorona rapidamente
Tendo a ver arquitetura de software como um conjunto de decisões de projeto que orienta a implementação
Pela minha experiência, a maioria dos arquitetos de software fornece diretrizes e estrutura para os engenheiros de software. Mas a descrição do C4, de “criar mapas do código existente em vários níveis de detalhe”, soa diferente. Não entendo por que diagramas de código seriam chamados de arquitetura de software. Isso é literalmente nível de código; como isso seria arquitetura? É como querer colocar o diagrama elétrico das tomadas na planta da casa. Se a ideia é “usar ferramentas de automação”, então seria documentar a base de código existente até o nível de função? Não vejo como isso ajuda a projetar e planejar software. Um mapa para explicar a estrutura de um software existente pode ser legal, mas, ao falar de padrões de projeto, ninguém entrega um mapa por função da implementação de um singleton. Basta dizer que é necessário um singleton ou um padrão de repositório. O próprio projeto de software claramente existe, e esse tipo de abordagem também parece válido para projeto, mas, pela minha experiência, projeto de software, implementação e arquitetura não são a mesma coisa, nem feitos pelas mesmas pessoas. Isso me parece mais próximo de design de sistemas, e o arquiteto de software teria o papel de orientar para que esse design de sistema siga bons princípios de arquitetura. Talvez eu esteja sendo exigente demais
Vejo como função essencial da arquitetura de software fornecer informação para que os desenvolvedores possam tomar decisões de projeto por conta própria, sem ter de escalar cada julgamento para uma autoridade. Dito isso, varia muito onde a arquitetura termina e onde o desenvolvimento começa. Acho que a própria arquitetura decide o que é importante do ponto de vista arquitetural. Se a arquitetura julga que algum detalhe de baixo nível da aplicação é importante, então ele também vira um detalhe arquitetural. Na prática, na maioria das organizações, a arquitetura controla pelo menos o projeto de alto nível, como componentes, padrões de comunicação, APIs e tecnologias usadas. Em algumas organizações, isso desce até classes individuais. Não todas as classes, mas as que modelam o domínio do problema, especialmente quando esse modelo é usado como linguagem em vários projetos ou implementado como artefato compartilhado. O C4 serve para organizações que tratam estruturas de nível mais baixo como preocupação arquitetural, indo além de uma lista da aplicação e das interfaces de integração
Basicamente, a ideia é ter diagramas para cada nível claramente distinto, único ou útil dentro do sistema. Se você precisa de um diagrama em nível de código, é bem possível que esteja fazendo um trabalho personalizado complexo ou especificando demais um projeto que poderia simplesmente ficar como detalhe de implementação
É parecido com a construção civil, onde arquiteto, engenheiro e responsável pela obra têm papéis diferentes. Fico curioso sobre onde traçar essa linha em arquitetura, projeto e implementação, e que preocupações cada uma deve tratar
Interessante, mas difícil ver que isso acrescente algo de especial
Diagramas de alto nível são bons, mas já dá para criá-los sem precisar ler um site bonito sobre modelo visual. O próprio site praticamente admite isso. É muito correto dizer que, embora a indústria tenha UML, ArchiMate e SysML, muitas equipes acabaram preferindo diagramas bem mais simples de “caixas e linhas”. Mas parece ignorar por que o diagrama de classes UML fracassou completamente. Ao mesmo tempo em que reconhece que ninguém gosta disso, o quarto C do modelo, código, acaba sendo um diagrama de classes UML. Isso não faz falta. Basta desenhar diagramas arbitrários com clareza e colocar rótulos nas setas. Os três primeiros diagramas, aliás, são um bom exemplo disso
Isso ajuda bastante quando estou pensando em conceitos novos ou fazendo brainstorming, porque a ferramenta não atrapalha. Hoje uso o Freeform; é bem simples, mas funciona bem. Você seleciona dois objetos, faz cmd-clique ou clique com o botão direito e aperta “add connecting line”
Há apenas alguns meses eu terminei mais um documento de arquitetura com uma boa quantidade de diagramas de classes, diagramas de sequência e casos de uso
É fácil os blocos virarem uma mistura de coisas de níveis diferentes. Algumas são abstratas, outras concretas, e outras apenas arbitrárias. Aí, quando você precisa montar pedaços maiores da arquitetura, como uma cadeia de suprimentos, por exemplo, na prática tem de refazer quase tudo. Há muito desperdício, e ninguém enxerga a arquitetura inteira com clareza suficiente, o que leva a mais desperdício e problemas de qualidade. Estranhamente, muitos engenheiros reagem de forma defensiva a abordagens mais formais, provavelmente porque não veem benefício imediato ou nunca lidaram com arquitetura em grande escala e, por isso, não percebem o problema
Isso mostra que engenharia de software ainda é um campo imaturo
No meu caso, já se passaram mais de 25 anos e ainda estamos tendo praticamente as mesmas discussões “básicas”. Isso não quer dizer que seja algo ruim, mas o progresso é lento, e também não dá para colocar a culpa só em uma empresa específica, consórcio ou interesse comercial
Quantas vezes você já viu alguém ficar subindo e descendo entre alto nível de detalhe, alta complexidade e simplicidade vista de longe dentro de uma mesma linha de raciocínio, a ponto de ficar difícil entender o que a pessoa quer dizer? O mesmo problema acontece quando um desenvolvedor pensa “é só desenhar algumas caixas e setas nesse quadro de qualquer jeito; na minha cabeça faz sentido, então é um bom diagrama”
Mesmo sem ser engenheiro civil, dá para entender imediatamente algo como uma planta e sentir que ela é útil
Mas, mesmo sendo um engenheiro de software profissional, esses diagramas de exemplo não parecem úteis o bastante nem informativos o suficiente para justificar o esforço. O código é multidimensional demais para ser aproximado por um desenho bidimensional, e isso não funciona bem. O que talvez tenha potencial são padrões de código arquitetural mais convencionados. Algo como concorrência estruturada, e talvez também alguma coisa em nível ainda mais alto
Plantas têm um contexto muito fixo e um escopo limitado. Por exemplo, não é preciso explicar o que é uma janela. Mas, em software, na maior parte do tempo, você realmente precisa explicar a “janela”. Como cada “janela” ou elemento é diferente, não dá para simplesmente dizer que isso é uma janela e copiar 20 vezes
Se o modelo C4 parece arbitrário demais e excessivamente especificado, no começo deste ano escrevi sobre uma prática alternativa: https://www.ilograph.com/blog/posts/concrete-diagramming-mod...
Gosto deste modelo e já precisei usar UML em arquitetura de segurança. Nessa área, consistência do contexto de mais alto nível até o código é o ponto central.
A simplicidade do modelo C4 é uma espécie de mecanismo de imposição. Se houver contexto ou componentes ocultos, eles precisam aparecer no modelo. Se há resistência até a algo tão simples assim, vejo isso como um sinal de que pode haver elementos escondidos. Em projetos grandes, normalmente de fato existem coisas assim. Quando você faz as pessoas esclarecerem o pensamento dessa forma, em vez de apenas deixar que proponham algo e mantenham o direito de criticar, elas passam a se comprometer com afirmações e ideias, e a autoridade fica mais distribuída. Isso também pode gerar bastante resistência. Mas isso não é um problema do modelo, e sim do que acontece quando o modelo encontra pessoas. Gosto da consistência e provavelmente usaria esse tipo de abordagem como referência para projeto de segurança
C4 é muito interessante e, na minha visão, lida bem com um problema específico da arquitetura de software
Ele desloca as camadas mais baixas da arquitetura — principalmente hardware e software de sistema — para uma abstração mais ampla, e faz com que o esforço se concentre nas coisas que estão na pilha acima. Combina surpreendentemente bem com a abordagem atual baseada em nuvem, conteinerizada e escalável. Nesse sentido, ArchiMate também é bom e há bastante sobreposição, mas ele está mais firmemente ancorado no lado de infraestrutura. No passado, usei uma abordagem de diagramas parecida com ArchiMate para reduzir conflitos entre sistemas e fontes de dados, e foi muito eficaz para mostrar como as coisas que compramos e integramos dão suporte a requisitos específicos de negócio e de fluxo de trabalho dos usuários. Dizer que essas coisas se desalinhavam da base de código é totalmente correto. Mas, quando é preciso analisar sistemas complexos ou comunicar sistemas e planos a um grupo maior, isso pode ser uma ferramenta excelente. É surpreendente quantas vezes não existe nenhuma documentação coesa, e apenas sentar por algumas semanas desenhando caixas e linhas de conexão já pode destravar e simplificar um trabalho frustrante que não conseguia avançar. Isso é especialmente verdadeiro quando várias equipes trabalham na mesma área. C4, ArchiMate, UML etc. são apenas linguagens de diagramação com restrições, que capturam conteúdos específicos que você quer comunicar, analisar e registrar. Não acho que sejam muito boas como ferramenta de planejamento prévio ou de design. Muita gente sofreu na época da grande febre do UML. A ideia era que uma organização de arquitetos principais precisava detalhar, de forma dolorosamente minuciosa, todos os aspectos do sistema até as definições de classes antes de se escrever uma única linha de código, e insanidades como “basta gerar o código a partir do diagrama” atormentaram muita gente. Quando a implementação real começava, aquelas milhares de horas de planejamento normalmente eram ignoradas, e os desenvolvedores acabavam fazendo do jeito que queriam mesmo.