Software design - Você entendeu o problema?
Tags: architecture, discovery, softwareengineering, devops
Published: 2023-10-05 17:18:23

> Esse é o primeiro artigo que escrevo sobre Discovery Técnico e minha ideia é abordar todas as etapas de forma detalhada e com exemplos práticos. Começaremos desde o entendimento inicial do problema até os entregáveis de arquitetura.

Acredito que, para a grande maioria das pessoas, quando começamos a ter contato com uma nova requisição, seja para a manutenção de algo ou para a implementação de algo novo, começamos simultaneamente a escrever mentalmente o código e o design da solução para aquele problema que ainda estamos conhecendo. Isso é natural, queremos resolver, e queremos resolver rapidamente, pois o backlog está suspirando em nosso cangote, e o prazo apertado ativa esse nosso instinto de sobrevivência, onde resolver logo é o melhor caminho. Porém, esse estado de alerta pode ser traiçoeiro, e você pode se fechar para entender o problema de fato. No meio do caminho, você pode ter o viés de uma solução pronta em sua cabeça. Conforme o problema vai tornando a sua solução inviável, existe o risco de você se apegar tanto a ela, e se deixar levar pela frustração. No pior dos casos, você pode manter a solução que veio precocemente, recorrendo a adaptações ou até abrindo mão de alguma regra ou outra, pois o foco aqui já não está mais no problema, ele se perdeu. Esqueça o código por enquanto; no primeiro momento, não existe algoritmo, não existe linguagem. Seu foco deve ser principalmente entender o problema e, para isso, o separaremos em dois pontos: dados e regras.

## Dados e Regras

Eu desenvolvi essa forma de organizar as coisas na minha mente, e se por acaso a adotei de algum lugar, juro que foi de forma inconsciente hehe.

### Dados

Vamos lá. Primeiro, falando sobre os Dados, eu os vejo como a matéria-prima que teremos que manipular. Neste momento, é importante compreender a natureza do dado (Oxi?), ou seja, o que quero dizer é que precisamos primeiro entender quais são os dados que serão inseridos na nossa aplicação, o que são, de onde vêm, do que se alimentam e como sobrevivem. O Dado pode ser mais livre e flexível, como uma String, ou pode seguir um padrão mais rígido, como uma lista enumerada com itens específicos.

Neste estágio inicial, gosto de criar um dicionário de dados, onde os organizo por tipo e pela semântica que possuem, além de verificar se são obrigatórios ou se têm algum tipo de restrição, por exemplo:

```
------  Pedido de Reparo ---------
|   Descrição.       |     Tipo.             |   Exemplo.   |   
| Relato             |   Texto               | "PC morreu"  |  
| Severidade         |   Inteiro             | 5            | 
| Status             |   Lista de Status     | "Cancelado"  | 
| Valor              |   Decimal             | 2,000.00     | 
| Data de Criação    |   Date                | 1993-08-26.  |
| Categoria          |   Lista de Categorias | "Informática"|
```

Perceba que estamos utilizando tipos primitivos para `Relato`, `Severidade`, `Valor` e `Data de Criação`. No entanto, para `Categoria` e `Status`, utilizaremos uma lista. Isso já me implica na necessidade de levantar as possibilidades dessa lista. Neste momento, vou apresentar apenas o exemplo para a categoria. Seguiríamos a mesma lógica para Status.

```
------ Categorias -----
|   Descrição    |     Tipo     |   Exemplo  
| Nome           |   Texto      | Informática 
```
------ Categorias Existentes

```
- Informática
- Escritório
- Eletrodomésticos
- Outros
```
 -----

Entender os dados te guiará para compreender o domínio de negócio. Saber como esses dados estão interconectados proporcionará uma noção inicial de como organizar esses domínios na sua abstração. Os dados vão nos guiar aos domínios de negócio, e estes, por sua vez, vão influenciar a arquitetura e o design. Portanto seja mais que um amigo, seja _friend_ dos dados e os conheça bem.

### Regras

Legal. Agora que tenho os dados organizados e uma compreensão inicial de como estão estruturados, é crucial aprender como esses dados se transformarão em regras. É neste momento que o dado ganha vida, quando eu oriento os fluxos dentro do sistema e capacito o sistema para a tomada de decisão. Escrever regras claras e precisas ajudará a eliminar possíveis ruídos de comunicação entre mim e a pessoa que fez a requisição (PM/PO/SM/BA e tantas outras siglas que representam nossos demandantes).

Mas como poderei avaliar se a minha regra está bem escrita? Evite descrever regras abstratas ou que exijam conhecimento prévio do negócio. Por exemplo:

> 1 - Cancelar casos antigos

O que define se um caso é antigo? Como posso tomar essa decisão com base nos dados disponíveis? 
Que tal a seguinte regra:

> 1 - Quando a data de criação do chamado for superior a dois dias da data atual, alterar o status do report para "Cancelado"

A regra proposta parece bem clara e precisa. Ela estabelece que, se a data de criação do chamado for superior a dois dias em relação à data atual, o status do Chamado deve ser alterado para "Cancelado". Isso proporciona uma orientação direta e mensurável para a ação a ser tomada.

Outro ponto importante é saber qual é o gatilho do fluxo em que implementaremos a regra. Em que momento na linha do tempo do nosso sistema isso vai acontecer? Deixar a regra solta, por mais bem escrita que esteja, não é suficiente. É necessário investigar as expectativas em relação a isso, talvez o stakeholder ainda não saiba que uma rotina precisa ser implementada. Nesse caso, poderíamos atualizar a regra:

> Ponto de disparo: Execução de rotina de revisão dos chamados
> **Dado** que existam chamados cadastrados
> 1 - **Quando** a data de criação do chamado for superior a dois dias da data atual, **então** alterar o status do report para "Cancelado"

Inseri um [Gherkin](https://cucumber.io/docs/gherkin/reference/) subliminar na regra acima. No entanto, o que é crucial aqui é deixarmos claro o evento que irá disparar nossa regra. É quando esse dado deixa o seu ninho confortável no disco rígido para ser arranhado pelas garras das nossas regras. Posteriormente, podemos entrar em detalhes técnicos, como se essa rotina é um Job no CTRL-M (Socorro DEUS), uma Lambda na AWS, um cronjob, entre outras opções. Neste momento, o essencial é que você vai tornar evidente para todos que as coisas não acontecem magicamente, e ninguém irá te reportar um BUG dizendo que o status não foi atualizado às 6 horas da manhã, quando na verdade essa rotina é executada às 7.

Menos importante do que decidir se utilizaremos um loop FOR, um operador ternário ou cinquenta estruturas IF aninhadas que se amontoam num monte horrendo fedendo à manutenção e à complexidade, é garantir, neste momento, que o comportamento esperado esteja baseado nos dados corretos e nos momentos certos.

Em resumo, uma boa regra possui clareza quanto aos dados de entrada, quando ela deve acontecer, o comportamento desejado e quais dados ele influencia na saída.

Depois de tudo, retornamos à reflexão "Entendi o Problema?". Talvez, ao longo dessa jornada, você perceba que o problema não está claro, nem mesmo para os Stakeholders. Isso será útil para eliminar os ruídos de comunicação ou para elucidar detalhes importantes de negócio que estão subentendidos por alguma pessoa ou área. Também te ajudará a antecipar possíveis blocks relacionados a falta de insumos de negócio.

A próxima pergunta é: "Apenas você entendeu o problema?"

Mas isso fica para uma próxima leitura. Agradeço a quem chegou até aqui e peço que, por favor, me ajude com seu feedback. Isso me permitirá saber se conteúdos como este podem auxiliar as pessoas nessa aventura que é o Desenvolvimento e a Arquitetura de Software.