Em muitos projetos, uma demanda chega com aparência de instrução suficiente: “incluir um campo”, “validar o cadastro”, “expor uma API” ou “automatizar uma rotina”. A implementação pode começar em minutos, especialmente quando há uma ferramenta de IA pronta para sugerir classes, métodos, SQL e testes. O problema não é a velocidade em si. É a possibilidade de acelerar uma interpretação que nunca foi confirmada.
Uma demanda curta quase sempre contém decisões ocultas. O que exatamente deve acontecer? Para quem? Em quais condições? O que conta como erro? Que dados não podem ser alterados? Qual tela, serviço ou processo legado será afetado? Sem respostas, o código pode estar sintaticamente correto e, ainda assim, materializar um comportamento inadequado.
O desenvolvimento orientado por especificação — frequentemente resumido como SDD, de Specification-Driven Development — propõe inverter uma ordem comum: antes de pedir código, define-se o comportamento que o software deve apresentar e as condições pelas quais esse comportamento será considerado aceitável. Código, arquitetura, testes e contribuições de IA passam a responder a essa referência.
Isso não exige transformar toda demanda em um documento extenso. Exige reduzir ambiguidades relevantes, tornar decisões inspecionáveis e construir uma cadeia entre intenção, implementação e verificação. Em Delphi, essa prática é útil tanto em aplicações visuais VCL e FireMonkey quanto em APIs, integrações e sistemas legados.
Conheça o livro e leia uma degustação: acesse a página oficial de SDD em Delphi.
O custo técnico da demanda vaga
A frase “o sistema deve validar o CPF” parece objetiva, mas deixa perguntas fundamentais em aberto. A validação ocorre enquanto o usuário digita, ao sair do campo ou apenas ao confirmar? Campos vazios são permitidos? Há distinção entre pessoa física e cadastro estrangeiro? A regra deve estar na tela, em uma classe de domínio, em uma API ou em mais de uma camada? O que acontece com registros antigos que já contêm valores inválidos?
Essas perguntas não são burocracia. Elas definem comportamento. Quando não são respondidas, cada pessoa envolvida preenche as lacunas com uma suposição. A IA faz o mesmo: recebe uma instrução incompleta e produz uma resposta plausível, não necessariamente a decisão correta para aquele produto.
Em aplicações Delphi, a ambiguidade também pode se espalhar entre camadas. Um evento de formulário pode concentrar regra de negócio; uma rotina de acesso a dados pode decidir algo que deveria estar em um serviço; uma API pode aceitar uma entrada que a interface bloqueia. Cada implementação isolada pode parecer razoável, mas o conjunto deixa de ter uma regra única.
A especificação funciona como um ponto de alinhamento. Ela não elimina a necessidade de julgamento técnico. Ao contrário: obriga a exercê-lo antes que decisões se tornem dependências no código, na base de dados, nos testes e no uso cotidiano do sistema.
Da intenção ao comportamento verificável
Uma especificação útil descreve o que pode ser observado e verificado. Em vez de registrar apenas “criar aprovação de pedidos”, ela deve tornar explícitas as condições, os resultados e as exceções da aprovação.
Considere uma formulação inicial:
Permitir que gestores aprovem pedidos de compra.
Ela pode ser desdobrada em elementos verificáveis:
- um pedido elegível pode ser aprovado por um usuário com determinada permissão;
- um pedido já aprovado não pode receber nova aprovação sem uma regra explícita de reabertura;
- pedidos sem itens não podem ser aprovados;
- a aprovação registra data, responsável e novo status;
- tentativas sem autorização retornam uma falha compreensível para o consumidor da regra, seja uma tela ou uma API.
O propósito não é antecipar toda linha de código. É criar uma definição que permita reconhecer se o resultado atende ao que foi pedido. A implementação poderá usar classes, interfaces, datasets, repositórios, comandos SQL ou serviços HTTP; o comportamento esperado permanece como referência para avaliar essas escolhas.
Contratos: o que entra, o que sai e o que não pode mudar
Um contrato delimita responsabilidades. Em uma rotina, ele pode explicitar pré-condições, pós-condições e invariantes.
As pré-condições indicam o que precisa ser verdadeiro antes da operação. Por exemplo: o identificador do pedido deve existir; o usuário deve estar autenticado; a solicitação deve conter uma justificativa quando a política a exigir.
As pós-condições indicam o resultado esperado depois da operação: se a aprovação for bem-sucedida, o status do pedido muda, a autoria é registrada e uma consulta posterior retorna o novo estado. Já os invariantes expressam regras que permanecem verdadeiras: um pedido cancelado não pode ser aprovado; o total aprovado não pode divergir do total calculado segundo a regra definida.
Em Delphi, esses contratos ajudam a decidir a fronteira entre uma unidade de interface e uma unidade de domínio. Um formulário VCL pode coletar a ação do usuário e apresentar mensagens. Uma classe de aplicação pode coordenar a operação. Uma classe de domínio ou serviço pode proteger a regra que não deve depender da tela. Não existe uma única estrutura obrigatória, mas o contrato torna mais claro onde a decisão precisa residir para continuar consistente.
Critérios de aceite não são sinônimo de tarefas
Um critério de aceite descreve como saber se a demanda foi atendida. “Criar botão Aprovar” é uma tarefa de interface. “Um usuário autorizado aprova um pedido elegível e o sistema registra a operação” é um comportamento que pode ser aceito ou rejeitado após verificação.
Essa diferença é especialmente importante quando uma equipe utiliza IA. Uma solicitação como “faça uma tela de aprovação” tende a gerar componentes e eventos. Uma solicitação baseada em critérios de aceite dá à ferramenta uma referência mais forte: ela precisa apoiar uma solução que preserve permissões, transições de estado, registros e respostas para erros.
Critérios de aceite também facilitam conversas entre áreas. Quem solicitou a mudança não precisa decidir a estrutura de classes, mas pode validar comportamentos de negócio. Quem implementa pode transformar os critérios em testes e em decisões de arquitetura. Assim, o acordo não fica restrito a uma interpretação de tela ou a um comentário em uma tarefa.
Casos de fronteira: onde as regras mostram sua forma
O caminho principal costuma ser simples: dados válidos entram, a operação é concluída, o usuário recebe uma confirmação. A maior parte das falhas de entendimento aparece nos limites.
Casos de fronteira incluem valores vazios, tamanhos máximo e mínimo, datas nos limites de um período, concorrência, repetição de requisições, dados parcialmente preenchidos, permissões insuficientes e estados incompatíveis. Eles não são detalhes posteriores; são parte da definição da regra.
Em uma API, por exemplo, não basta dizer que o endpoint aprova um pedido. É necessário indicar o que ocorre se a chamada for repetida, se o pedido tiver sido cancelado entre a consulta e a aprovação, se a autenticação não tiver a permissão necessária ou se uma integração enviar um identificador inexistente. Em uma aplicação de interface, as mesmas questões existem, mesmo que apareçam como botões desabilitados, mensagens ou bloqueios de navegação.
Uma prática objetiva é listar, para cada comportamento, pelo menos quatro grupos de cenários:
- Sucesso esperado: a operação ocorre com dados válidos e no estado permitido.
- Entrada inválida: faltam informações, há formato incorreto ou valor fora da regra.
- Estado inválido: os dados existem, mas a operação não é permitida naquele momento.
- Falha de integração ou persistência: a regra foi solicitada corretamente, mas uma dependência não respondeu como esperado.
Essa lista não substitui a análise do domínio. Ela cria um roteiro para não tratar apenas o cenário mais confortável. Também oferece material para testes automatizados, testes manuais e revisão de código.
Rastreabilidade: ligar decisões a código e testes
Especificar não significa produzir um arquivo que será esquecido depois da reunião. A especificação ganha valor quando permanece conectada ao trabalho técnico.
Rastreabilidade é a capacidade de relacionar uma necessidade a seus critérios de aceite, decisões de arquitetura, pontos de implementação e testes. Não é preciso adotar um processo pesado para praticá-la. Em uma demanda pequena, uma identificação curta e consistente já pode cumprir essa função.
Imagine o item APR-03: “Pedidos cancelados não podem ser aprovados”. Essa regra pode aparecer na especificação, em um teste de unidade para a operação de aprovação, em uma mensagem apresentada pela API e em uma revisão de código da classe responsável. Se alguém alterar a regra, sabe onde procurar os efeitos esperados.
Essa conexão reduz dois problemas comuns. O primeiro é o teste que verifica apenas a implementação atual, sem confirmar a intenção original. O segundo é a alteração aparentemente local que quebra um comportamento em outra camada. Ao rastrear a regra, fica mais fácil perguntar: qual critério foi alterado? Quais testes precisam ser revistos? Quais consumidores da API ou telas dependem disso?
Em sistemas legados, a rastreabilidade é ainda mais valiosa. Muitas regras vivem em eventos, procedimentos armazenados, validações duplicadas ou convenções não documentadas. Antes de reescrever uma parte do sistema, a equipe pode identificar o comportamento preservado, o comportamento indesejado e o comportamento ainda desconhecido. A modernização deixa de ser apenas uma troca de tecnologia e se torna uma investigação orientada por evidências.
Como a IA participa sem assumir a direção
Ferramentas de IA podem contribuir em várias etapas: transformar uma descrição em cenários iniciais, sugerir perguntas sobre exceções, propor esqueleto de testes, resumir uma unidade extensa, comparar um contrato com uma implementação ou gerar alternativas de código. Essas possibilidades são úteis, mas dependem da qualidade do contexto oferecido.
A IA não conhece automaticamente as regras particulares do sistema, o significado dos estados em uma tabela, as decisões históricas da arquitetura ou as consequências de uma mudança em produção. Mesmo quando sugere código Delphi compilável, ainda é necessário avaliar se a solução respeita contratos, segurança, tratamento de erros, estilo do projeto e compatibilidade com dependências existentes.
Uma forma responsável de usar IA é atribuir a ela tarefas delimitadas e critérios explícitos. Por exemplo:
- apresentar o contrato de uma operação e pedir cenários de teste, incluindo entradas inválidas e transições de estado proibidas;
- fornecer uma interface já definida e solicitar uma implementação inicial, exigindo que não altere o contrato;
- pedir que a ferramenta identifique divergências entre critérios de aceite e um trecho de código, para revisão humana;
- solicitar alternativas de refatoração, informando quais comportamentos devem ser preservados.
O ponto central é que a saída da IA deve ser tratada como material de engenharia a ser analisado, não como autoridade sobre a regra. A responsabilidade técnica continua com quem decide o contrato, revisa o código, executa os testes e responde pelos efeitos da mudança.
Contexto demais também pode ser um problema
Há uma tendência de tentar resolver respostas genéricas despejando grandes volumes de código e documentação em uma conversa com IA. Isso pode dificultar a análise, expor informações desnecessárias e ocultar a pergunta principal.
Uma alternativa é fornecer contexto progressivo: primeiro, o objetivo e os critérios de aceite; depois, as interfaces ou unidades diretamente envolvidas; por fim, as restrições técnicas necessárias para a tarefa. Em vez de perguntar “corrija esse projeto”, é mais útil perguntar “verifique se este método atende ao critério APR-03 sem alterar a assinatura pública”.
A precisão do pedido não garante uma resposta perfeita, mas aumenta a capacidade de revisar a resposta segundo uma referência objetiva.
Um roteiro prático para a próxima demanda
O desenvolvimento orientado por especificação pode começar sem uma reforma completa no processo da equipe. Escolha uma demanda de tamanho controlado e percorra as etapas a seguir.
1. Escreva a mudança como comportamento
Substitua títulos genéricos por uma frase que descreva ator, ação e resultado. Em vez de “ajustar pedidos”, prefira “usuário autorizado aprova pedido elegível e o sistema registra a aprovação”.
2. Explicite as condições e exceções
Liste dados obrigatórios, permissões, estados permitidos, estados proibidos e efeitos esperados. Inclua ao menos alguns casos de fronteira. Se houver dúvida de negócio, registre-a como dúvida; não a esconda como decisão de código.
3. Defina critérios de aceite observáveis
Os critérios devem permitir verificação por alguém que conheça a regra. Evite frases como “funcionar corretamente”. Prefira condições que possam ser reproduzidas em uma tela, em uma chamada de API ou em um teste.
4. Decida as fronteiras técnicas
Identifique onde cada responsabilidade ficará: interface, serviço de aplicação, domínio, persistência ou integração. A arquitetura não precisa ser desenhada em excesso, mas as regras críticas precisam ter uma casa definida para evitar duplicação.
5. Derive testes da especificação
Transforme os cenários em testes de unidade, integração ou aceitação conforme a camada envolvida. O teste não deve apenas provar que o método atual retorna algo; deve verificar o comportamento acordado, inclusive nas falhas relevantes.
6. Use IA com uma pergunta verificável
Peça contribuições específicas: cenários ausentes, implementação de uma parte delimitada, leitura crítica de inconsistências ou sugestão de testes. Revise a resposta contra o contrato e o código existente. Se não houver critério para avaliar a resposta, a tarefa ainda está vaga demais.
7. Atualize a cadeia quando a regra mudar
Mudanças são normais. Quando uma decisão de negócio for alterada, atualize o critério, os testes e os pontos de implementação relacionados. Essa disciplina simples evita que a documentação passe a contar uma história diferente do sistema.
Limitações e cuidados da abordagem
Especificação não é previsão completa. Alguns comportamentos só se tornam claros quando usuários interagem com uma versão do sistema, quando uma integração revela restrições ou quando uma regra de negócio muda. O objetivo não é congelar o aprendizado, e sim registrar o melhor entendimento disponível para que a mudança seja consciente.
Também não é necessário especificar tudo com o mesmo grau de detalhe. Um ajuste visual de baixo risco pede menos formalidade que uma regra financeira, uma autorização de acesso ou uma operação que altera dados de forma irreversível. O nível de precisão deve acompanhar o risco, a complexidade e o custo de errar.
Outro cuidado é evitar que a especificação vire duplicação literal do código. Ela deve conservar a linguagem do comportamento e das decisões, não reproduzir nomes de variáveis ou estruturas internas que podem mudar. Quando a especificação descreve apenas a implementação atual, ela deixa de servir como critério independente de avaliação.
Por fim, IA não resolve falta de decisão. Ela pode ampliar alternativas e reduzir trabalho repetitivo, mas também pode produzir respostas convincentes para premissas equivocadas. Quanto maior o impacto de uma alteração, maior deve ser a qualidade da revisão, da validação e da responsabilidade humana sobre ela.
Conclusão
A especificação orientada por comportamento cria uma referência comum para análise, arquitetura, código e testes. Ao explicitar contratos, critérios de aceite, casos de fronteira e relações entre artefatos, a equipe diminui o espaço ocupado por suposições silenciosas. Isso é relevante em qualquer tecnologia, mas ganha importância particular em ambientes Delphi que combinam aplicações visuais, APIs, integrações e código legado.
A IA pode acelerar partes desse trabalho, desde que receba contexto delimitado e seja submetida a critérios verificáveis. Ela participa da engenharia; não substitui a análise nem a responsabilidade técnica de quem mantém o sistema.
Para aprofundar esse método no contexto da linguagem e de seus diferentes cenários de uso, o livro SDD em Delphi, de Régys Borges da Silveira, aborda a especificação no centro do desenvolvimento apoiado por IA, conectando contratos, critérios de aceite, casos de fronteira, rastreabilidade, arquitetura, código e testes. Os exemplos percorrem VCL, FireMonkey, APIs, legados, agentes, RAG e MCP. A obra está em sua 1ª edição, publicada em 2026, com 528 páginas, em português do Brasil, disponível nos formatos físico e Kindle.
Se o tema fizer sentido para seu contexto, vale conhecer a página oficial e ler a degustação disponibilizada para a obra.
Referências
SILVEIRA, Régys Borges da. SDD em Delphi. 1. ed. 2026. Disponível em: https://livros.regys.com.br/sdd-em-delphi. Acesso em: 28 set. 2026.
Descubra mais sobre Régys Borges da Silveira
Assine para receber nossas notícias mais recentes por e-mail.
Dê-nos sua opinião, seu comentário ajuda o site a crescer e melhorar a qualidade dos artigos.