Construção e evolução de software
Ambientes, versões, integração, entrega, alterações, manutenção e desenvolvimento assistido por IA.
Uma colega recebe o repositório e não consegue correr os testes: desconhece as versões das ferramentas, a configuração necessária e a preparação dos dados. Entregar o código não basta para permitir a continuação do trabalho. A construção inclui código, configuração, dependências e automação. A evolução conserva o valor do produto quando necessidades e ambiente mudam.
Ambiente reproduzível
O ambiente de desenvolvimento reúne linguagem, ferramentas, dependências e serviços necessários. Regista versões, instruções e configuração de exemplo, para que um colega consiga obter o projeto e executar as verificações sem adivinhar configurações.
Não guardes segredos no repositório. Uma configuração de exemplo mostra os nomes necessários; credenciais pertencem ao mecanismo acordado para o ambiente. Se o projeto precisa de uma base de dados, explica como criar dados de teste sem usar dados pessoais reais.
Uma atualização de dependência pode mudar comportamento. Fixar versões ajuda a reproduzir; não dispensa atualizar e verificar quando há uma necessidade.
Versões e alterações
O controlo de versões regista estados e mudanças. Um commit deve representar uma alteração compreensível. Um branch permite trabalhar numa linha separada; um merge integra linhas de desenvolvimento; um tag identifica um estado, frequentemente uma versão publicada.
Um pedido de integração, como um pull request, apresenta a mudança, a razão, os efeitos e a evidência. A revisão deve permitir a outra pessoa entender o comportamento sem conhecer a conversa que originou o trabalho.
Para mudar a duração máxima de 120 para 180 minutos, seguimos a cadeia completa.
| Passo | Evidência |
|---|---|
| Pedido | issue com requisito e motivo |
| Impacto | regra, mensagens, testes de fronteira, documentação |
| Alteração | commit pequeno com a regra e os testes |
| Verificação | CI com unidade, integração e sistema |
| Entrega | release com notas e migração de dados se preciso |
A rastreabilidade evita corrigir apenas o ecrã e deixar o servidor com outra regra. Integração incremental significa juntar cada passo ao ramo principal e correr a suíte, em vez de guardar semanas de trabalho para uma grande integração final.
Um conflito de merge é uma incompatibilidade textual que precisa de resolução. Mas uma integração sem conflitos textuais também pode estar errada: duas alterações podem compilar e discordar sobre o significado de um estado.
Integração contínua
Na CI, continuous integration, integramos mudanças frequentemente e verificamos o estado combinado de forma automatizada. Um pipeline pode construir, analisar código, correr testes e produzir artefactos.
Para as reservas, os testes de unidade avaliam regras, os de integração avaliam armazenamento e os de sistema exercitam cenários críticos. Se o pipeline falhar, a equipa investiga antes de acrescentar mudanças sobre um estado incerto.
Um pipeline verde dá evidência das verificações executadas naquele ambiente. Não demonstra que um requisito em falta foi satisfeito. Os resultados devem identificar a revisão e os artefactos verificados, para sabermos a que versão se aplica essa evidência.
Entrega e implantação
Continuous delivery mantém o produto num estado em que pode ser entregue, com a preparação automatizada. Continuous deployment implanta automaticamente mudanças que passam os critérios definidos. A equipa deve dizer qual usa e onde existe uma decisão de entrega.
DevOps aproxima desenvolvimento e operação: a equipa considera construção, entrega, observação e recuperação ao longo do ciclo. Não é apenas o nome de um ficheiro de automação.
Uma nova versão precisa de saber como instalar, observar falhas e recuperar. Por exemplo, a versão nova guarda uma série de reservas recorrentes num formato que a anterior não entende. Repor só o executável antigo pode impedir a leitura dessas reservas.
O plano de recuperação precisa, por isso, de tratar os dados, a compatibilidade entre versões e as migrações necessárias.
Manutenção
A manutenção modifica software em uso. Em sistemas por medida, os custos de manutenção costumam exceder os custos de desenvolvimento inicial, por isso estas decisões pesam no orçamento total. Distinguimos o motivo principal:
| Tipo | Motivo | Exemplo |
|---|---|---|
| Corretiva | Corrigir defeito | Impedir duas reservas sobrepostas |
| Adaptativa | Responder à mudança de ambiente | Suportar nova API de horários |
| Perfetiva | Melhorar ou acrescentar capacidade | Permitir reservas recorrentes |
| Preventiva | Reduzir problemas futuros | Remover duplicação preservando resultados |
Uma alteração pode servir vários motivos, por isso classifica pelo contexto, não pela quantidade de linhas. Na evolução, acrescentamos e alteramos capacidades; numa fase de servicing, mantemos a operação com correções e adaptação ao ambiente, sem novas funcionalidades. Durante a descontinuação, ou phase-out, o sistema ainda pode ser usado, mas deixa de receber alterações, e a retirada termina o seu uso e exige planear dados, substituição e dependências.
Sistemas legados
Um sistema legado continua a ter valor, apesar de tecnologias ou estrutura difíceis de manter. Antigo não significa inútil, e moderno não significa melhor.
Para decidir entre manter, transformar, substituir ou retirar, avaliamos o valor para o negócio e a qualidade técnica. Um sistema de alto valor e boa qualidade pode continuar em uso. Se mantém alto valor mas tem baixa qualidade, precisamos de reduzir o risco técnico sem perder o que ainda faz bem.
Reescrever tudo pode ser mais arriscado do que transformar gradualmente. Antes de substituir, precisamos de compreender as regras escondidas no comportamento atual e os dados históricos.
IA no ciclo de vida
Uma ferramenta de IA pode sugerir requisitos, protótipos, código, testes ou hipóteses de diagnóstico, mas a equipa continua responsável pelas decisões e pela evidência. Uma sugestão plausível pode omitir regras do domínio ou usar uma API inexistente.
No exemplo, a ferramenta gera a verificação consultar livre e depois guardar. O código parece funcionar num teste sequencial, mas não protege a concorrência. Revemos o requisito, identificamos a corrida e exigimos uma operação atómica e um caso concorrente. Registar a sugestão, a decisão tomada e as verificações permite explicar por que a equipa aceitou ou rejeitou o resultado. Confirma com os docentes as regras de declaração de uso de IA do teu projeto. Live Programming e LiveSD aparecem nos materiais como apoio à construção assistida, não como substitutos da decisão e da evidência.
Os testes gerados também precisam de oráculos independentes. Se a ferramenta inventar a regra e o resultado esperado, ambos podem concordar e estar errados. Não partilhes dados privados ou segredos para obter sugestões.
Ciclos de feedback mais curtos permitem aprender cedo. Se a geração produz mais mudanças do que a equipa consegue avaliar, a revisão pode tornar-se o bloqueio. Divide mudanças por objetivo e risco, conserva decisões compreensíveis e observa o produto em uso.
Um pedido de mudança completo
Para acrescentar reservas recorrentes, começamos por analisar regras: cada ocorrência pode falhar? Cancelar uma implica cancelar todas? Que períodos suportamos? Depois avaliamos impacto no modelo, armazenamento, interface, testes e migração.
Implementamos um incremento delimitado, verificamos e documentamos. A mudança termina quando temos um comportamento observado e uma forma de o manter, não quando o código foi escrito.
Exercícios
Porque mudamos o sistema?
Classifica: corrigir uma reserva duplicada; adaptar à nova API de salas; acrescentar recorrência; extrair duplicação sem alterar resultados. Considera ainda a mesma mudança no código, máximo de 120 para 180 minutos, em dois contextos: a escola altera a regra de 120 para 180; a escola sempre exigiu 180, mas o programa usa 120. Classifica e justifica a diferença.
Pista
O motivo principal importa mais do que o tamanho da alteração.
Mais uma pista
Pergunta se corrigimos um defeito, mudamos ambiente, acrescentamos capacidade ou reduzimos risco futuro.
Solução
São, respetivamente, manutenção corretiva, adaptativa, perfetiva e preventiva. A última pode usar refactoring se preservar resultados. Uma alteração real pode ter vários motivos. Classifica pelo motivo principal e explica o contexto. No primeiro contexto do limite, responder ao pedido novo é perfetiva. No segundo, restaurar a regra já acordada é corretiva. O diff pode ser igual; o motivo e o comportamento anteriormente esperado distinguem as classificações.
Confere a tua resposta:
- Classifiquei correção como corretiva e API como adaptativa.
- Classifiquei recorrência como perfetiva.
- Classifiquei a extração preventiva, se preservar comportamento.
- Distingui aumentar o máximo por pedido novo de corrigir um limite mal implementado.
Erros frequentes
Não chames adaptativa a qualquer funcionalidade nova. Não confundas preventiva com uma mudança já necessária por erro observado.
Pipeline verde e produto entregue
Cada integração produz um artefacto testado. Uma pessoa decide quando o implantar. É continuous delivery ou continuous deployment? O pipeline verde prova a validação com utilizadores?
Pista
Pergunta se a implantação acontece sem decisão humana adicional.
Solução
É continuous delivery se a preparação mantém o produto entregável e a implantação depende de decisão humana. Continuous deployment implanta automaticamente após os critérios. O verde demonstra os checks executados nessa revisão, não que todas as necessidades foram validadas com utilizadores.
Confere a tua resposta:
- Identifiquei continuous delivery com decisão de implantação.
- Distingui implantação automática de preparação automatizada.
- Limitei a evidência aos checks executados.
Erros frequentes
Não confundas um artefacto construído com uma versão já em uso. Não atribuas ao pipeline requisitos que nunca verificou.