Introdução ao Structurizr

Introdução ao Structurizr

1. Introdução

Este artigo é sobre Structurizr, uma ferramenta que fornece umprogrammatic approach to architectural definitions and visualizations based on the C4 Model.

O Structurizr quebra com as abordagens tradicionais de arrastar e soltar dos editores de diagrama de arquitetura, como UML, e nos permite descrever nossos artefatos de arquitetura usando a ferramenta que conhecemos melhor: Java.

2. Começando

Para começar, vamos adicionar a dependênciastructurizr-core ao nossopom.xml:


    com.structurizr
    structurizr-core
    1.0.0-RC5

3. Sistemas

Vamos começar a modelar uma arquitetura de amostra. Suponha que estejamos construindo um terminal de pagamento com capacidade de detecção de fraude usado por comerciantes para compensar pagamentos.

Primeiro, precisamos criar umWorkspacee umModel:

Workspace workspace = new Workspace("Payment Gateway", "Payment Gateway");
Model model = workspace.getModel();

Também definimos um usuário e dois sistemas de software nesse modelo:

Person user = model.addPerson("Merchant", "Merchant");
SoftwareSystem paymentTerminal = model.addSoftwareSystem(
  "Payment Terminal", "Payment Terminal");
user.uses(paymentTerminal, "Makes payment");
SoftwareSystem fraudDetector = model.addSoftwareSystem(
  "Fraud Detector", "Fraud Detector");
paymentTerminal.uses(fraudDetector, "Obtains fraud score");

Agora que nosso sistema está definido, podemos criar uma visão:

ViewSet viewSet = workspace.getViews();

SystemContextView contextView = viewSet.createSystemContextView(
  paymentTerminal, "context", "Payment Gateway Diagram");
contextView.addAllSoftwareSystems();
contextView.addAllPeople();

Aqui, criamos uma visão que inclui todos os sistemas e pessoas de software. Agora a visualização precisa ser renderizada.

4. Ver via PlantUML

Na seção anterior, criamos uma visualização de um gateway de pagamento simples.

O próximo passo é criar um diagrama amigável ao ser humano. Provavelmente, a solução mais simples para uma organização que já usaPlantUML seria instruir o Structurizr a fazer uma exportação PlantUML:

StringWriter stringWriter = new StringWriter();
PlantUMLWriter plantUMLWriter = new PlantUMLWriter();
plantUMLWriter.write(workspace, stringWriter);
System.out.println(stringWriter.toString());

Aqui, a marcação resultante é impressa na tela, mas pode ser enviada com a mesma facilidade para um arquivo. A renderização dos dados dessa maneira produz o diagrama abaixo:

image

5. Veja através do site da Structurizr

Existe outra opção para renderizar diagramas. Uma visualização de arquitetura pode ser enviada ao site do Structurizr por meio de uma API do cliente. O diagrama será gerado usando sua rica interface do usuário.

Vamos criar um cliente API:

StructurizrClient client = new StructurizrClient("key", "secret");

Os parâmetros chave e secretos são obtidos no painel da área de trabalho em seu site. O espaço de trabalho pode ser referido por:

client.putWorkspace(1337, workspace);

Obviamente, precisamos nos registrar no site e criar um espaço de trabalho. Uma conta básica com um único espaço de trabalho é gratuita. Ao mesmo tempo, planos comerciais também estão disponíveis.

6. Containers

Vamos estender nosso sistema de software adicionando alguns contêineres. Em um modelo C4, os contêineres podem ser aplicativos da Web, aplicativos móveis, aplicativos de desktop, bancos de dados e sistemas de arquivos: praticamente qualquer coisa que contenha código e / ou dados.

Primeiro, criamos alguns contêineres para o nosso terminal de pagamento:

Container f5 = paymentTerminal.addContainer(
  "Payment Load Balancer", "Payment Load Balancer", "F5");
Container jvm1 = paymentTerminal.addContainer(
  "JVM-1", "JVM-1", "Java Virtual Machine");
Container jvm2 = paymentTerminal.addContainer(
  "JVM-2", "JVM-2", "Java Virtual Machine");
Container jvm3 = paymentTerminal.addContainer(
  "JVM-3", "JVM-3", "Java Virtual Machine");
Container oracle = paymentTerminal.addContainer(
  "oracleDB", "Oracle Database", "RDBMS");

Em seguida, definimos relacionamentos entre esses elementos recém-criados:

f5.uses(jvm1, "route");
f5.uses(jvm2, "route");
f5.uses(jvm3, "route");

jvm1.uses(oracle, "storage");
jvm2.uses(oracle, "storage");
jvm3.uses(oracle, "storage");

Por fim, crie uma exibição de contêiner que possa ser alimentada a um renderizador:

ContainerView view = workspace.getViews()
  .createContainerView(paymentTerminal, "F5", "Container View");
view.addAllContainers();

A renderização do diagrama resultante via PlantUML produz:

image

7. Componentes

O próximo nível de detalhe no modelo C4 é fornecido pela visualização do componente. Criar um é semelhante ao que fizemos antes.

Primeiro, criamos alguns componentes em um contêiner:

Component jaxrs = jvm1.addComponent("jaxrs-jersey",
  "restful webservice implementation", "rest");
Component gemfire = jvm1.addComponent("gemfire",
  "Clustered Cache Gemfire", "cache");
Component hibernate = jvm1.addComponent("hibernate",
  "Data Access Layer", "jpa");

A seguir, vamos adicionar alguns relacionamentos:

jaxrs.uses(gemfire, "");
gemfire.uses(hibernate, "");

Por fim, vamos criar a visualização:

ComponentView componentView = workspace.getViews()
  .createComponentView(jvm1, JVM_COMPOSITION, "JVM Components");

componentView.addAllComponents();

Uma versão do diagrama resultante via PlantUML resulta em:

image

8. Extração de componente

Para bases de código existentes usando a estrutura Spring, o Structurizr fornece uma maneira automatizada de extrair componentes anotados pelo Spring e adicioná-los aos artefatos arquitetônicos.

Para utilizar esse recurso, precisamos adicionar mais uma dependência:


    com.structurizr
    structurizr-spring
    1.0.0-RC5

Em seguida, precisamos criar umComponentFinder configurado com uma ou mais estratégias de resolução. As estratégias de resolução afetam coisas como quais componentes serão adicionados ao modelo, profundidade da passagem da árvore de dependência etc.

Podemos até adicionar estratégias de resolução personalizadas:

ComponentFinder componentFinder = new ComponentFinder(
  jvm, "com.example.structurizr",
  new SpringComponentFinderStrategy(
    new ReferencedTypesSupportingTypesStrategy()
  ),
  new SourceCodeComponentFinderStrategy(new File("/path/to/base"), 150));

Finalmente, começamos o localizador:

componentFinder.findComponents();

O código acima verifica o pacotecom.example.structurizr em busca de beans anotados com Spring e os adiciona como componentes à JVM do contêiner. Não é preciso dizer que somos livres para implementar nossos próprios scanners, recursos anotados JAX-RS e até mesmo fichários do Google Guice.

Um exemplo de um diagrama simples de um projeto de amostra é reproduzido abaixo:

image

9. Conclusão

Este tutorial rápido aborda os conceitos básicos do projeto Structurizr for Java.

E, como sempre, o código de exemplo pode ser encontradoover on GitHub.