Iniciando com C4 Model

Simon Brown – Criador do C4 Model

Ele foi desenvolvido por Simon Brown, um arquiteto de software e consultor, e é amplamente utilizado por equipes de desenvolvimento de software em todo o mundo.

Para começar a usar o C4 Model, você precisará de uma ferramenta de modelagem de arquitetura, como o Microsoft Visio ou o PlantUML. Recomendo usar o PlantUML e integrar com o VSCode através de sua extensão. Em breve, vou elaborar um tutorial de uso do PlantUML com o VSCode, mas por enquanto, você pode visualizar os diagramas no servidor do PlantUML no link abaixo:

https://www.plantuml.com/plantuml

Isto posto, vamos seguir os seguintes passos:

Defina o escopo do sistema: antes de começar a modelar a arquitetura, é importante definir o escopo do sistema que você está trabalhando. Isso ajudará a determinar os componentes que devem ser incluídos no modelo e a orientar o nível de detalhe que será necessário.

Crie um diagrama de contexto: o primeiro nível do C4 Model é o diagrama de contexto, que deve mostrar os principais componentes externos ao sistema, como clientes, fornecedores e usuários finais, bem como o contexto em que o sistema será utilizado.

Crie um diagrama de contêiner: o segundo nível do C4 Model é o diagrama de contêiner, que deve mostrar os principais componentes do sistema, como servidores, banco de dados e aplicativos, bem como as dependências entre eles.

Adicione seus diagramas de classes à documentação do projeto para aumentar o nível de detalhamento no quarto nível do modelo C4.

O C4 Model é composto por quatro níveis hierárquicos:

Nível de contexto

Neste nível, são mostrados os principais componentes externos ao sistema, como clientes, fornecedores e usuários finais, bem como o contexto em que o sistema será utilizado.

@startuml C4_Context
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml

LAYOUT_LEFT_RIGHT()

Person(customer, "Cliente", "Cliente de uma concessionaria")
Person(dealer, "Concessionaria", "Concessionaria de veiculos")
Person(supplier, "Fornecedor", "Fornecedor de veiculos")

System_Boundary(system_app, "Aplicação Web") {
    System(web_app, "Sistema de Anúncios", "Exibe lista de veículos disponíveis para venda, possibilitando a escolha de um veículo e a compra do mesmo.")
}

Rel(customer, web_app, "Escolhe um veículo", "HTTP")
Rel(web_app, dealer, "Notifica", "E-mail")
Rel_L(dealer, supplier, "Comunica", "E-mail")
Rel(supplier, dealer, "Confirma venda", "E-mail")
Rel(web_app, customer, "Notifica", "E-mail")
@enduml

Comece importando a biblioteca de Context do C4 Model:
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml

' Indica a direção dos blocos no diagrama:
LAYOUT_LEFT_RIGHT()
' Cria as pessoas (atores) do diagrama:
Person(customer, "Cliente", "Cliente de uma concessionaria")
Person(dealer, "Concessionaria", "Concessionaria de veiculos")
Person(supplier, "Fornecedor", "Fornecedor de veiculos")
' Defina os limites do sistema:
System_Boundary(system_app, "Aplicação Web") {
    System(web_app, "Sistema de Anúncios", "Exibe lista de veículos disponíveis para venda, possibilitando a escolha de um veículo e a compra do mesmo.")
}
' Defina os relacionamentos e ações de cada elemento:
Rel(customer, web_app, "Escolhe um veículo", "HTTP")
Rel(web_app, dealer, "Notifica", "E-mail")
Rel_L(dealer, supplier, "Comunica", "E-mail")
Rel(supplier, dealer, "Confirma venda", "E-mail")
Rel(web_app, customer, "Notifica", "E-mail")

' Rel: Define um relacionamento padrao
' Rel_L: Força um elemento fique à ESQUERDA do elemento relacionado
' Rel_R: Força um elemento fique à DIREITA do elemento relacionado

Nível de contêiner

Neste nível, são mostrados os principais componentes do sistema, como servidores, banco de dados e aplicativos, bem como as dependências entre eles.

@startuml C4_Container
!include  https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

LAYOUT_LEFT_RIGHT()

Person(customer, "Cliente", "Cliente de uma concessionaria")
Person(dealer, "Concessionaria", "Concessionaria de veiculos")
Person(supplier, "Fornecedor", "Fornecedor de veiculos")

System_Boundary(advertising, "Sistema de Anúncios") {
    Container(next_app, "Sistema de Anúncios", "NextJS", "Permite ao cliente visualizar e enviar proposta de compra dos veículos")
}

Rel(dealer, supplier, "Compra veiculo", "HTTP")
Rel(customer, next_app, "Pesquisa veiculo", "HTTP")
Rel(dealer, next_app, "Pesquisa veiculo", "HTTP")
Rel(supplier, next_app, "Pesquisa veiculo", "HTTP")
Rel(next_app, customer, "Mostra veiculo", "HTTP")
Rel(next_app, dealer, "Mostra veiculo", "HTTP")
Rel(next_app, supplier, "Mostra veiculo", "HTTP")
@enduml

Nível de componente

Neste nível, são mostrados os componentes mais detalhados do sistema, incluindo classes, módulos e pacotes de software.

@startuml C4_Component
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml

' Diagrama c4 model de componentes
' para mais informações, veja https://c4model.com/

Person(customer, "Cliente", "Cliente de uma concessionaria")
Person(dealer, "Concessionaria", "Concessionaria de veiculos")
Person(supplier, "Fornecedor", "Fornecedor de veiculos")

System_Boundary(car_dealership, "Concessionaria de Veiculos") {
    Container(web_app, "Aplicacao Web", "Java, Spring MVC", "Exibe a lista de veiculos")
    Container(rest_api, "API REST", "Java, Spring MVC", "Exibe a lista de veiculos")
    Container(database, "Banco de Dados", "PostgreSQL", "Armazena os dados dos veiculos")
}

Rel(customer, web_app, "Visualiza a lista de veiculos")
Rel(customer, rest_api, "Visualiza a lista de veiculos")
Rel(dealer, web_app, "Visualiza a lista de veiculos")
Rel(dealer, rest_api, "Visualiza a lista de veiculos")
Rel(supplier, database, "Armazena os dados dos veiculos")

@enduml

Nível de classe

Neste nível, são mostrados os detalhes da implementação do código, como as interfaces e as classes concretas. Os detalhes mais profundos podem ser adicionados à medida que o projeto for se desenvolvendo. Num primeiro momento, apenas o nome das classes e seus relacionamentos já é suficiente. Pra esse exemplo, vou adicionar um diagrama de classes com as propriedades e métodos para passar uma idéia mais completa.

@startuml Class_Diagram

title Diagrama de Classes

' create a package for the classes
package "Classes" {
    class Customer
    class Dealer
    class Supplier
    class Vehicle
    class Car
    class Truck
    class Motorcycle
}

class Customer {
    -String name
    -String address
    -String phone
    -String email
    +String getName()
    +String getAddress()
    +String getPhone()
    +String getEmail()
    +void setName(String name)
    +void setAddress(String address)
    +void setPhone(String phone)
    +void setEmail(String email)
}

class Dealer {
    -String name
    -String address
    -String phone
    -String email
    +String getName()
    +String getAddress()
    +String getPhone()
    +String getEmail()
    +void setName(String name)
    +void setAddress(String address)
    +void setPhone(String phone)
    +void setEmail(String email)
}

class Supplier {
    -String name
    -String address
    -String phone
    -String email
    +String getName()
    +String getAddress()
    +String getPhone()
    +String getEmail()
    +void setName(String name)
    +void setAddress(String address)
    +void setPhone(String phone)
    +void setEmail(String email)
}

class Vehicle {
    -String make
    -String model
    -String year
    -String color
    -String vin
    -String licensePlate
    -String mileage
    -String price
    +String getMake()
    +String getModel()
    +String getYear()
    +String getColor()
    +String getVin()
    +String getLicensePlate()
    +String getMileage()
    +String getPrice()
    +void setMake(String make)
    +void setModel(String model)
    +void setYear(String year)
    +void setColor(String color)
    +void setVin(String vin)
    +void setLicensePlate(String licensePlate)
    +void setMileage(String mileage)
    +void setPrice(String price)
}

class Car extends Vehicle {
    -String engine
    -String transmission
    -String fuelType
    -String driveType
    -String bodyStyle
    -String interiorColor
    -String exteriorColor
    -String mileage
    -String price
    +String getEngine()
    +String getTransmission()
    +String getFuelType()
    +String getDriveType()
    +String getBodyStyle()
    +String getInteriorColor()
    +String getExteriorColor()
    +String getMileage()
    +String getPrice()
    +void setEngine(String engine)
    +void setTransmission(String transmission)
    +void setFuelType(String fuelType)
    +void setDriveType(String driveType)
    +void setBodyStyle(String bodyStyle)
    +void setInteriorColor(String interiorColor)
    +void setExteriorColor(String exteriorColor)
    +void setMileage(String mileage)
    +void setPrice(String price)
}

class Truck extends Vehicle {
    -String engine
    -String transmission
    -String fuelType
    -String driveType
    -String bodyStyle
    -String interiorColor
    -String exteriorColor
    -String mileage
    -String price
    +String getEngine()
    +String getTransmission()
    +String getFuelType()
    +String getDriveType()
    +String getBodyStyle()
    +String getInteriorColor()
    +String getExteriorColor()
    +String getMileage()
    +String getPrice()
    +void setEngine(String engine)
    +void setTransmission(String transmission)
    +void setFuelType(String fuelType)
    +void setDriveType(String driveType)
    +void setBodyStyle(String bodyStyle)
    +void setInteriorColor(String interiorColor)
    +void setExteriorColor(String exteriorColor)
    +void setMileage(String mileage)
    +void setPrice(String price)
}

class Motorcycle extends Vehicle {
    -String engine
    -String transmission
    -String fuelType
    -String driveType
    -String bodyStyle
    -String interiorColor
    -String exteriorColor
    -String mileage
    -String price
    +String getEngine()
    +String getTransmission()
    +String getFuelType()
    +String getDriveType()
    +String getBodyStyle()
    +String getInteriorColor()
    +String getExteriorColor()
    +String getMileage()
    +String getPrice()
    +void setEngine(String engine)
    +void setTransmission(String transmission)
    +void setFuelType(String fuelType)
    +void setDriveType(String driveType)
    +void setBodyStyle(String bodyStyle)
    +void setInteriorColor(String interiorColor)
    +void setExteriorColor(String exteriorColor)
    +void setMileage(String mileage)
    +void setPrice(String price)
}

Customer "1" -- "1..*" Vehicle : compra
Dealer "1" -- "1..*" Vehicle : gerencia
Dealer "1" -- "1..*" Supplier : comunica
Supplier "1" -- "1..*" Vehicle : fornece
Vehicle "1" -- "1..*" Car
Vehicle "1" -- "1..*" Truck
Vehicle "1" -- "1..*" Motorcycle
@enduml

Bom, pra começar já temos um bom material!

Documentar a arquitetura de um software é importante por diversas razões. Algumas dessas razões incluem:

Comunicação: A documentação da arquitetura permite que os membros do time compreendam como o software foi projetado e como os componentes se relacionam uns com os outros. Isso facilita a comunicação e a colaboração entre os membros do time, pois todos estão trabalhando a partir de uma base comum de conhecimento.

Manutenção: A documentação da arquitetura também é útil para a manutenção do software, pois permite que novos desenvolvedores entendam rapidamente como o software foi projetado e como ele funciona. Isso pode tornar mais fácil identificar problemas e implementar soluções.

Evolução: A documentação da arquitetura também é importante para o planejamento de futuras alterações e evoluções no software. Isso permite que o time tenha uma visão clara de como o software está atualmente e como ele pode ser modificado de maneira a manter a integridade e a qualidade do software.

Utilizar o C4 Model para documentar a arquitetura de um software pode ajudar a garantir que a documentação seja completa e precisa, e pode ser uma ferramenta útil para comunicar a arquitetura do software aos membros do time e a outros stakeholders.

Por enquanto, é isso! Fique ligado que em breve teremos mais artigos sobre arquitetura de software, documentação e muito mais.

Vlw :=)

Facebook
Twitter
LinkedIn
Arquitetura de Software

Observabilidade: Dados e métricas antes de Ferramentas

E aí, pessoal! Beleza? Hoje vamos falar sobre um assunto elementar no desenvolvimento e manutenção de produtos de software como serviço (SaaS): Dados e métricas antes de ferramentas, em especial no contexto

Arquitetura de Software

O Códificador Limpo – Robert C. Martin

“O Codificador Limpo” de Robert C. Martin é um livro essencial para todos os desenvolvedores de software que desejam aprimorar suas habilidades em programação e produzir um código limpo e de qualidade.

Resumos de livros

Resumo do livro: Mindset

“Mindset: The New Psychology of Success” é um livro escrito pela psicóloga Carol S. Dweck. O livro fala sobre a importância da mentalidade em relação ao sucesso e apresenta duas tipos de

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *