Geralmente, os requisitos funcionais são mais difíceis de serem especificados do que os requisitos não funcionais. Entretanto, ao serem adequadamente especificados não podemos garantir a construção de especificações completas e consistentes.
Comente esta afirmação considerando um requisito funcional, e os requisitos não funcionais a eles associados. Utilize o sistema especificado em sala de aula para ilustrar a sua resposta.
Passo 1
O enunciado pede que eu comente a afirmação: “Geralmente, os requisitos funcionais são mais difíceis de serem especificados do que os requisitos não funcionais. Entretanto, ao serem adequadamente especificados não podemos garantir a construção de especificações completas e consistentes.”
As perguntas que preciso responder são: (1) por que requisitos funcionais (RF) costumam ser mais difíceis de especificar que requisitos não funcionais (RNF)? (2) por que, mesmo quando bem especificados, não se pode garantir completude e consistência das especificações? (3) ilustrar tudo isso com um requisito funcional e os RNF associados para um sistema prático.
Informações relevantes que vou usar (escolhi um sistema clássico para exemplificar): o sistema é um “Sistema de Gerenciamento de Biblioteca” (o mesmo tipo de sistema frequentemente usado em disciplinas de requisitos). Vou focar num requisito funcional específico: “emprestar um item bibliográfico a um usuário”. Vou também listar os requisitos não funcionais tipicamente associados a esse RF (desempenho, disponibilidade, segurança, concorrência, auditabilidade, usabilidade, escalabilidade, integridade dos dados).
As perguntas que preciso responder são: (1) por que requisitos funcionais (RF) costumam ser mais difíceis de especificar que requisitos não funcionais (RNF)? (2) por que, mesmo quando bem especificados, não se pode garantir completude e consistência das especificações? (3) ilustrar tudo isso com um requisito funcional e os RNF associados para um sistema prático.
Informações relevantes que vou usar (escolhi um sistema clássico para exemplificar): o sistema é um “Sistema de Gerenciamento de Biblioteca” (o mesmo tipo de sistema frequentemente usado em disciplinas de requisitos). Vou focar num requisito funcional específico: “emprestar um item bibliográfico a um usuário”. Vou também listar os requisitos não funcionais tipicamente associados a esse RF (desempenho, disponibilidade, segurança, concorrência, auditabilidade, usabilidade, escalabilidade, integridade dos dados).
Passo 2
Por que requisitos funcionais tendem a ser mais difíceis de especificar? Vou explicar com calma e exemplos práticos do RF “emprestar um item”.
- Linguagem natural é ambígua. Se eu escrevo: “O sistema empresta livros aos usuários”, isso deixa dúvidas: que é “emprestar”? quais regras? um usuário pode tomar qualquer item? por quanto tempo? que tipos de itens (livro físico, e-book)? Exemplo concreto: “disponível” pode significar “não emprestado”, mas também pode depender de reserva, estado físico (danificado) ou disponibilidade para empréstimo interbibliotecas.
- Muitos caminhos e exceções. Um mesmo RF contém vários fluxos: fluxo principal (sucesso), fluxos alternativos (item indisponível, usuário com multa, limite de empréstimos atingido), exceções (erro de base de dados, perda de conexão). Especificar todos os fluxos aumenta a complexidade.
- Regras de negócio escondidas. Políticas institucionais (prazo variado por tipo de usuário, prioridade para docentes) frequentemente não são totalmente declaradas inicialmente. Por exemplo: “docentes podem renovar
vezes” — quem define isso? falta explicitação. - Interação com outros requisitos e sistemas. Empréstimo envolve autenticação, inventário, cobranças, notificações — cada interação pode introduzir requisitos adicionais ou restrições.
- Evolução e stakeholders múltiplos. Bibliotecários, alunos, TI, diretoria têm visões distintas; cada grupo pode acrescentar requisitos conflitantes ou incompletos.
Eu mostro agora como a frase ambígua gera problemas: com a especificação “O sistema empresta livros aos usuários”, já surgem perguntas não respondidas: quem pode emprestar? quais itens? quais prazos? há multas? renovações? reservas? Assim, o RF é, na prática, um pacote de comportamentos que precisa ser decomposto.
Passo 3
Como transformar um RF vago em uma especificação mais “adequada”? Vou ensinar técnicas e o que cada uma faz — e por que mesmo assim não temos garantia absoluta de completude/consistência.
- Use cases / fluxos de interação: descrevem passo a passo o que acontece no fluxo principal e nos alternativos. Exemplo para empréstimo: fluxo principal (autenticar usuário → verificar elegibilidade → verificar disponibilidade → registrar empréstimo → confirmar). Fluxos alternativos (usuário com multa → bloquear empréstimo; item reservado por outro → sugerir reserva; base de dados indisponível → operação em modo degradado).
- O que é um fluxo principal: sequência mais comum que leva ao sucesso. Fluxos alternativos: desvios que ocorrem sob condições específicas.
- Pré e pós-condições (contratos): definir exatamente o que precisa ser verdadeiro antes e depois. Exemplo: pré-condição: usuário autenticado e verificado; pós-condição: registro de empréstimo criado com data de devolução. Isso ajuda a reduzir ambiguidades.
- Critérios de aceitação testáveis: por exemplo, “quando um usuário sem multas e com menos de
empréstimos ativos solicita um livro disponível, o sistema deve retornar confirmação de empréstimo em no máximo segundos”. Critério testável = mensurável. - Modelos formais ou semi-formais (diagramas de estados, sequências, tabelas de decisão, especificações em linguagens como Alloy/Z para partes críticas): servem para detectar inconsistências lógicas, mas exigem habilidade técnica.
Mesmo aplicando essas técnicas, duas limitações importantes permanecem:
- Não é praticável enumerar todas as situações possíveis (mundo aberto): usuários podem inventar usos inesperados; interações com falhas de hardware, redes e terceiros geram cenários não previstos.
- Conflitos entre requisitos podem surgir depois que se combinam as especificações (por exemplo, um RNF pode contradizer um RF ou outro RNF). Detectar automaticamente todas as contradições é, em geral, difícil — em sistemas complexos, a análise global é trabalhosa e pode até ser indecidível na prática.
Passo 4
Agora eu apresento um exemplo detalhado e didático de especificação do RF “emprestar item” e os RNF associados, mostrando como cada RNF refina ou impõe restrições:
- Requisito funcional (RF-EMPRÉSTIMO): “Permitir que um usuário com conta válida empreste um item bibliográfico.”
- Pré-condições (claro e testável): o usuário está autenticado; o usuário não possui bloqueio por multas pendentes; o número de empréstimos ativos do usuário é menor que
; o item está em catalogação como ‘emprestável’ e seu estado físico permite empréstimo. - Fluxo principal (passo a passo):
- Usuário autentica-se no sistema.
- Sistema verifica elegibilidade (multa, limite de empréstimos).
- Sistema verifica disponibilidade do item (não emprestado e não reservado por terceiro).
- Se disponível, sistema cria registro de empréstimo com data de devolução calculada.
- Sistema decrementa disponibilidade no inventário e envia confirmação ao usuário.
- Fluxos alternativos (exemplos):
- Usuário com multa → sistema informa bloqueio e apresenta instruções para pagamento.
- Item reservado → sistema informa que item reservado e oferece colocar o usuário na fila de reserva.
- Erro de banco de dados → sistema tenta operação atômica; se falha, não altera inventário e notifica o usuário com código de erro.
- Pós-condições: registro de empréstimo criado; inventário consistente; notificação enviada; operação é atômica (ou seja, tudo ocorre ou nada ocorre).
- Pré-condições (claro e testável): o usuário está autenticado; o usuário não possui bloqueio por multas pendentes; o número de empréstimos ativos do usuário é menor que
- Requisitos não funcionais associados (para o mesmo RF):
- RNF-DESENV (desempenho): a operação de empréstimo bem-sucedida deve ser confirmada em no máximo
segundos sob carga normal. - RNF-DISP (disponibilidade): serviço de empréstimo deve ter disponibilidade de
(janelas de manutenção planejada excluídas). - RNF-SEG (segurança): apenas usuários autenticados e autorizados podem executar empréstimos; todas as operações que alteram inventário devem ser registradas em log de auditoria com identidade e timestamp imutável.
- RNF-CONC (concorrência/integridade): o sistema deve garantir que dois usuários não consigam emprestar o mesmo exemplar físico simultaneamente (controle transacional, lock ou mecanismo equivalente).
- RNF-USAB (usabilidade): o fluxo de empréstimo deve ser completável em no máximo
cliques para um operador humano em posto de atendimento. - RNF-ESC (escalabilidade): o sistema deve suportar picos de
operações por minuto sem violar RNF-DESENV.
Cada RNF é mensurável e testável, o que ajuda a transformar desejos vagos em critérios verificáveis.
- RNF-DESENV (desempenho): a operação de empréstimo bem-sucedida deve ser confirmada em no máximo
Passo 5
Vou explicar conflitos práticos entre os RF e RNF no exemplo — e por que isso impede garantias absolutas de consistência/completude:
- Conflito desempenho versus consistência: para garantir RNF-CONC (nenhum empréstimo duplicado), podemos usar bloqueios fortes em banco de dados. Isso preserva consistência, mas pode aumentar latência e reduzir RNF-DESENV e RNF-ESC. Se o requisito de desempenho for rígido, pode haver contradição.
- Segurança versus usabilidade/desempenho: exigir autenticação multifator para cada empréstimo aumenta segurança (RNF-SEG) mas piora usabilidade (RNF-USAB) e possivelmente desempenho (RNF-DESENV).
- Disponibilidade versus consistência (cenário distribuído): para alta disponibilidade em replicação geograficamente distribuída, ajustar políticas pode levar à possibilidade de leituras/atualizações temporariamente inconsistentes — é o clássico trade-off (não dá para garantir simultaneamente máxima disponibilidade, tolerância a partições e forte consistência em todas as condições).
- Requisitos não especificados inicialmente: uma nova necessidade (por exemplo, suportar empréstimo entre bibliotecas parceiras) pode invalidar pré-condições e criar inconsistência com requisitos anteriores.
Esses exemplos mostram que, mesmo com RF bem estruturados e RNF mensuráveis, quando o sistema é articulado por completo aparecem trade-offs e possíveis contradições que exigem decisões de projeto e priorização — ou seja, não existe uma “única especificação correta” que automaticamente seja completa e consistente em todos os aspectos.
Passo 6
Como mitigar (mas não eliminar) os problemas e reduzir o risco de incompletude/inconsistência — práticas que devo aplicar em provas e na vida real:
- Priorizar requisitos e explicitar trade-offs: documentar quais RNF têm prioridade sobre outros (por exemplo, consistência sobre desempenho para registros financeiros).
- Traçabilidade: manter rastreabilidade RF ↔ RNF ↔ casos de teste ↔ código ajuda a detectar impactos quando algo muda.
- Critérios de aceitação e testes automatizados: cada RF e RNF deve ter testes que verifiquem comportamento e métricas; isso reduz surpresas.
- Prototipagem e iteração: construir protótipos para validar suposições de usabilidade e desempenho com usuários reais.
- Revisões cruzadas com stakeholders: envolver bibliotecários, usuários, TI para capturar regras de negócio escondidas.
- Isolar partes críticas e aplicar verificação formal: para funcionalidades críticas (por ex., integridade de empréstimos e cobranças) usar especificações formais/verification unitária.
- Plano de evolução: aceitar que requisitos mudam; ter processo de gerenciamento de mudanças e reavaliação de consistência.
Combinando essas práticas reduz-se muito a probabilidade de problemas graves, mas não se pode afirmar que a especificação seja absolutamente completa e consistente para sempre.
Passo 7
Resumo final do raciocínio (amigável e encorajador): RFs parecem mais difíceis de especificar porque descrevem comportamentos ricos em variantes, exceções e regras de negócio implícitas; exigem decomposição em muitos fluxos e pré/post-condições para ficar claros. RNFs, quando bem metrificados, ajudam a tornar RFs testáveis, mas trazem restrições cross-cutting que frequentemente entram em conflito entre si ou com RFs. Mesmo com boas técnicas (use cases, contratos, critérios de aceitação, testes e verificação), condições inerentes ao mundo real — mudanças de requisitos, interações complexas, falhas e trade-offs arquiteturais — impedem garantias formais de completude e consistência da especificação como um todo. A abordagem prática é reduzir risco com precisão, teste, priorização e iteração, não esperar uma especificação perfeita e imutável.
Resposta
Requisitos funcionais costumam ser mais difíceis de especificar porque descrevem comportamentos ricos, cheios de exceções e regras de negócio implícitas, exigindo decomposição detalhada (fluxos, pré/post-condições, critérios de aceitação). Requisitos não funcionais são complementares e, quando metrificados, tornam RFs mais verificáveis, mas também criam restrições que podem conflitar com RFs e entre si (por exemplo, desempenho versus consistência ou segurança versus usabilidade). Mesmo com especificações bem elaboradas (use cases, pré/post-condições, RNFs mensuráveis, testes automatizados, revisão com stakeholders), não se pode garantir completude e consistência absoluta devido a mudanças de requisitos, interações complexas, cenários não previstos e trade-offs arquiteturais — a melhor prática é detectar e mitigar inconsistências por priorização, rastreabilidade, prototipagem e verificação, aceitando que resta sempre algum risco residual.