XP e ciclos de feedback
Valores, práticas técnicas, TDD, programação em par, integração e desenho simples.
A escola pede para mudar a duração máxima de duas para três horas sem partir reservas existentes. Extreme Programming, XP, reúne práticas técnicas e de colaboração para desenvolver com requisitos incertos ou em mudança. As práticas apoiam-se umas nas outras: alterar o desenho frequentemente precisa de feedback de testes e integração para detetar regressões.
Valores e práticas
Comunicação esclarece necessidades e decisões. Simplicidade evita construir para hipóteses não confirmadas. Feedback mostra se as decisões funcionam. Coragem permite corrigir uma solução inadequada. Respeito permite discutir o trabalho e partilhar responsabilidade sem culpar pessoas.
As práticas tornam estes valores concretos:
| Prática | Feedback ou efeito |
|---|---|
| Planning game | Negociar prioridades com estimativas da equipa |
| Small releases | Observar cedo o uso do produto |
| Whole team | Ter acesso às pessoas que esclarecem necessidades |
| Pair programming | Rever decisões enquanto são implementadas |
| Test-driven development | Verificar exemplos de comportamento antes de acrescentar código |
| Continuous integration | Descobrir incompatibilidades entre alterações |
| Refactoring | Melhorar estrutura preservando comportamento |
| Simple design | Resolver as necessidades presentes com uma estrutura compreensível |
| Coding standards | Tornar código partilhado consistente |
| Collective ownership | Permitir alterações por toda a equipa com as verificações acordadas |
| System metaphor | Partilhar uma descrição que ajude a compreender o sistema |
| Sustainable pace | Manter um ritmo que permita atenção e qualidade |
Propriedade coletiva não dispensa coordenação: duas pessoas a alterar a mesma regra precisam de comunicar. Um ritmo sustentável também não significa que todas as semanas terão o mesmo trabalho.
Planning game
O cliente ou representante identifica necessidades e prioridades; a equipa estima e explica consequências. As decisões de conteúdo e data precisam de respeitar a capacidade e o risco.
Na aplicação, consultar disponibilidade tem valor antes de personalizar cores. A equipa pode revelar que a API de salas é incerta e propor uma experiência antes de assumir a entrega. As prioridades vêm do valor e dos riscos, não da tarefa que parece mais agradável.
Scrum organiza o trabalho através de responsabilidades, artefactos e eventos, enquanto XP explicita práticas de construção. Por isso podemos usar práticas de XP numa equipa Scrum sem tratar os dois nomes como sinónimos.
Prioridade, estimativa e compromisso
O cliente prefere três histórias que a equipa estima em 5, 3 e 4 pontos. A capacidade prevista para a iteração é oito pontos. A prioridade não torna possível concluir os doze: cliente e equipa precisam de negociar conteúdo e data com base nas estimativas e nas dependências.
Se as duas primeiras histórias forem independentes e produzirem resultados úteis, podem formar um plano inicial de oito pontos. A terceira fica para uma decisão seguinte. Essa soma apoia uma previsão, não garante que a equipa terminará: uma dependência nova ou um erro na estimativa pode obrigar a rever o plano. O cliente explica o valor e ordena necessidades; a equipa estima o trabalho e esclarece as consequências técnicas. Nenhum dos lados resolve a diferença impondo valores fictícios.
TDD
No Test-Driven Development, TDD, trabalhamos num ciclo curto:
- Escrevemos um teste para um pequeno comportamento ainda ausente.
- Corremos o teste e observamos uma falha que demonstra essa ausência.
- Implementamos o necessário para o teste passar.
- Revemos a estrutura, preservando os comportamentos, e voltamos a correr os testes.
Os nomes habituais são red, green e refactor, mas uma falha de importação ou um teste que nunca chegou à condição pretendida não demonstra o comportamento ausente. Para a duração válida entre 30 e 120 minutos, seguimos um ciclo concreto.
- Red. Escrevemos
espera(aceitarDuracao(29) == false). Corremos e observamos falha porque a função ainda aceita 29. A falha mostra a condição errada, não um erro de importação. - Green. Acrescentamos a recusa quando
minutos < 30, preservando a recusa acima de 120. O teste passa. Não alteramos outra regra. - Refactor. Extraímos os limites para constantes com nomes. Voltamos a correr os testes de 29, 30, 120 e 121. Todos passam com os resultados da regra.
O resultado esperado vem da regra acordada, não do valor devolvido pelo código atual. Escalas de feedback diferentes protegem riscos diferentes: o teste de unidade responde em segundos, a integração com armazenamento demora mais, e a validação com estudantes demora dias mas revela necessidades erradas.
Os testes de aceitação, definidos com o cliente, verificam o sistema completo: uma história conta-se como terminada quando os testes de aceitação acordados passam, mantendo as restantes condições de Done, como integração, revisão e qualidade. Passar um conjunto escolhido de testes não prova, por si só, todos os requisitos. TDD ajuda a clarificar interfaces e obter feedback, mas não descobre automaticamente todos os requisitos nem substitui testes de integração, revisão ou validação com utilizadores.
Refactoring
Refactoring altera a estrutura interna sem alterar o comportamento observável: extrair uma regra repetida para um módulo pode ser refactoring se preservar os resultados. Mudar o máximo de 120 para 180 minutos altera a regra e não é só refactoring; pode haver trabalho de desenho na mesma alteração, mas devemos distinguir a mudança funcional da preservação de comportamento.
Antes de extrair a regra, confirmamos os comportamentos existentes. Depois fazemos passos pequenos e voltamos a verificá-los. Os testes são uma proteção parcial; também temos de observar contratos, dados persistidos e efeitos que não estejam cobertos.
Programação em par
No pair programming, o driver escreve e o navigator acompanha decisões e riscos. Trocam de papéis regularmente.
Ao implementar reservas, o navigator pode perguntar como a regra se comporta em intervalos adjacentes ou em duas tentativas concorrentes. O par discute essas hipóteses antes de as deixar escondidas no código. O navigator participa no raciocínio, além de detetar erros de sintaxe.
A prática pode partilhar conhecimento e funcionar como revisão contínua. A qualidade desse feedback depende das perguntas que a dupla faz.
Integração e entregas pequenas
Integração contínua implica integrar frequentemente num estado partilhado e obter feedback automatizado. Não basta configurar uma ferramenta e deixar branches separados durante semanas. Uma alteração pequena é mais fácil de entender e de localizar quando provoca uma falha.
Uma entrega pequena deve ser útil e verificável. Mostrar disponibilidade real numa sala pode ser um incremento, enquanto mostrar todos os ecrãs com dados fictícios pode ser apenas um protótipo. Ambos podem ter valor, mas respondem a perguntas diferentes.
Desenho simples
YAGNI, you aren’t gonna need it, lembra que uma necessidade possível não é uma necessidade confirmada. Não construímos suporte a pagamentos internacionais se o produto apenas reserva salas gratuitas.
Isso não justifica um desenho descuidado. Precisamos de preservar as regras presentes e tornar as alterações compreensíveis. Testes, interfaces e revisão ajudam a manter esse equilíbrio durante a construção e evolução.
Exercícios
Extração ou mudança funcional?
A equipa extrai a validação repetida para uma função e muda o máximo de 120 para 180 minutos. Pode chamar a toda a alteração refactoring?
Pista
Solução
Não. A extração pode preservar comportamento, mas o limite novo altera uma regra: 150 minutos passa de recusado a aceite. Convém separar em dois passos. Primeiro extrai com testes de 29, 30, 120 e 121. Depois muda o limite com novo requisito e novas expectativas.
Confere a tua resposta:
- Identifiquei a extração como possível refactoring se preservar comportamento.
- Identifiquei a mudança de limite como alteração funcional.
- Pedi verificação separada das regras antigas e novas.
Erros frequentes
Não uses refactoring como nome de qualquer melhoria. Um comportamento novo precisa de uma expectativa nova.
Uma falha que não prova o teste
A função já existe, mas o teste de recusa de 29 minutos importa-a de um ficheiro errado e falha antes de a chamar. A equipa diz que já observou red e pode implementar a regra. Avalia.
Pista
Solução
Primeiro corrigimos a preparação para o teste chegar à regra. Depois observamos se 29 é aceite indevidamente. Se o teste já passar, o comportamento existe e não precisamos de alterar a regra para este caso. Se falhar pela aceitação indevida, temos evidência para implementar a recusa pretendida.
Confere a tua resposta:
- Identifiquei a falha de preparação.
- Exigi executar a condição pretendida.
- Expliquei que red deve demonstrar o comportamento ausente.
Erros frequentes
Não contes qualquer erro de execução como prova da regressão ou necessidade funcional.
Prioridade não reduz o trabalho
O cliente ordena emitir bilhete, consultar bilhetes e transferir bilhete. A equipa estima 5, 3 e 4 pontos. As histórias são independentes, úteis e suficientemente pequenas. A capacidade prevista é oito pontos. O cliente pede para registar 2 em vez de 4 na transferência e entregar tudo. Avalia e propõe um plano inicial coerente com o Planning Game.
Solução
O total é 5 + 3 + 4 = 12 pontos. Mudar o registo para 2 não reduz o trabalho e ainda dá 10, acima de oito. A equipa explica as hipóteses da estimativa; pode revê-la se descobrir informação nova, mas não para esconder a diferença. Um plano inicial é emitir e consultar, 5 + 3 = 8, mantendo transferência para negociação de uma entrega seguinte. Cliente e equipa também podem discutir outro âmbito ou data. Os oito pontos são previsão de capacidade, não garantia de conclusão; os critérios de qualidade continuam a valer.
Confere a tua resposta:
- Somei doze pontos e identifiquei que excedem a previsão de oito.
- Mantive prioridades do cliente e estimativas justificadas pela equipa.
- Propus âmbito delimitado ou negociação de data, sem prometer a entrega.