Caro cliente, é por isso que essa mudança levou tanto tempo.

Mudanças em sistemas complexos de software parecem levar uma eternidade, certo? Mesmo os engenheiros costumam pensar que as mudanças estão indo além do que deveria ser, embora estejamos cientes da complexidade do sistema!

Para os clientes, a situação é ainda mais incompreensível. O problema é agravado pela complexidade aleatória, que é adicionada ao longo do tempo devido ao pouco suporte do sistema. Há uma sensação de que estamos tentando recolher água de um navio com mil buracos.

Portanto, mais cedo ou mais tarde, o cliente enviará uma carta: "Por que diabos leva tanto tempo?" Não devemos esquecer que nós, como engenheiros de software, temos uma janela para o mundo, da qual eles muitas vezes não têm. Eles confiam muito em nós, mas às vezes uma mudança aparentemente insignificante leva muito tempo. Por isso, surgem dúvidas.

Não se ofenda com esta pergunta; aproveite para mostrar empatia e dar a uma pessoa uma imagem mais clara da complexidade do sistema. Ao mesmo tempo, você pode sugerir maneiras de melhorar a situação. Quando alguém está chateado, este é o melhor momento para oferecer uma solução!

Uma carta é publicada abaixo, que, de uma forma ou de outra, enviamos repetidamente ao longo dos anos. Esperamos que ajude você a responder a essas perguntas.

Uma carta


Prezado Cliente,

Vi seu comentário no cartão “Notificar antes do término da tarefa” e terei prazer em discuti-lo em nossa próxima reunião. Aqui, para referência, vou resumir meus pensamentos, não é necessário responder.

Parafraseando sua anotação:

A alteração do prazo para concluir as tarefas em um dia para notificação por correio deve levar uma linha. Como pode demorar 4-8 horas? O que estou perdendo?

Por um lado, eu concordo com você. Simplesmente altere a parte da solicitação de tasks due <= today para tasks due <= tomorrow .

Por outro lado, reduzindo-o a uma idéia tão simplificada, ignoramos inadvertidamente a complexidade inerente e tomamos várias decisões de engenharia. Alguns deles devemos discutir.

Parte 1. Por que essa pequena mudança é mais do que parece?


Essa é uma alteração pequena e simples, uma linha de código. Passar o dia inteiro nele, mesmo meio dia, parece excessivo.

Obviamente, você não pode simplesmente implementar uma alteração na produção sem executar pelo menos localmente ou em um servidor de teste. Você deve garantir que o código seja executado corretamente e, se a solicitação for alterada, você precisará comparar a saída e garantir que ela pareça mais ou menos correta.

Aqui, comparar a saída pode ser mínimo, apenas uma pequena verificação pontual: verifique se os resultados fazem sentido etc. Essa é uma notificação para funcionários internos. Se a matemática por data estiver incorreta (um pequeno erro), ouviremos rapidamente sobre as equipes. Se fosse, por exemplo, um email para seus clientes, seria necessário um estudo mais aprofundado. Porém, para esse teste e revisão fáceis, 20 a 40 minutos são suficientes, dependendo se algo estranho ou inesperado aparece. A escavação de dados pode demorar algum tempo. Emitir alterações sem realizar uma revisão é simplesmente negligência não profissional.

Assim, adicionamos tempo para a logística normal, como confirmar um código, mesclar alterações, implantar, etc .: desde o início do trabalho até a liberação na produção, pelo menos uma hora se passa por um engenheiro profissional competente.

Obviamente, isso pressupõe que você saiba exatamente qual linha de código alterar. O fluxo de trabalho da tarefa reside basicamente no sistema antigo, mas algumas partes da lógica residem no novo sistema. Mover a lógica do sistema antigo é bom, mas significa que a funcionalidade da tarefa está atualmente dividida em dois sistemas.

Como trabalhamos juntos há tanto tempo, nossa equipe sabe qual processo envia um email com uma tarefa expirada e pode apontar para uma linha de código no novo sistema que inicia o processo. Portanto, não precisamos perder tempo descobrindo isso.

Porém, se observarmos o código da tarefa no sistema antigo, há pelo menos quatro maneiras diferentes de determinar se a tarefa está vencida. Além disso, observando os padrões e o comportamento do email, há pelo menos mais dois lugares em que parece que a lógica personalizada para esta tarefa é implementada.

E então a lógica da notificação é mais complicada do que você pensava. Distingue entre tarefas gerais e individuais, abertas e privadas, repetidas, a função de notificação adicional do gerente em caso de uma tarefa vencida, etc. Mas podemos descobrir rapidamente que, de fato, apenas 2 das 6+ definições da tarefa vencida são usadas para notificações. E apenas uma coisa precisa ser alterada para atingir a meta.

Essa revisão pode facilmente levar mais meia hora, talvez menos, se você esteve recentemente nesta parte da base de código. Além disso, a complexidade latente significa que podemos exceder nossa estimativa para testes manuais. Mas vamos adicionar 30 minutos para um esforço extra.

Assim, chegamos a 1,5 horas para nos sentirmos confiantes de que a mudança será realizada conforme o esperado.

Obviamente, ainda não verificamos se outros processos usam uma consulta mutável. Não queremos interromper acidentalmente outras funções alterando o conceito de “prazo final” para o dia que antecede o último dia para concluir a tarefa. Devemos considerar a base de código deste ponto de vista. Nesse caso, parece não haver grandes dependências - provavelmente porque a maior parte da interface do usuário ainda está no sistema antigo. Portanto, não há necessidade de se preocupar em alterar ou testar outros processos. Na melhor das hipóteses, isso leva mais 15 a 30 minutos.

Ah, e como a parte principal da interface com o usuário da tarefa ainda está no sistema antigo, precisamos realmente fazer uma rápida visão geral da funcionalidade da tarefa nesse sistema e garantir que o feedback esteja correto. Por exemplo, se a interface do usuário destacar tarefas cujo prazo chegou, podemos alterar essa lógica para corresponder à notificação. Ou pelo menos volte e pergunte ao cliente como ele deseja fazer isso. Recentemente, não examinei a funcionalidade da tarefa no sistema antigo e não me lembro se ela tem alguma idéia do prazo / atraso. Esta revisão adiciona mais 15 a 30 minutos. Talvez mais se o sistema antigo também tiver várias definições de uma "tarefa" etc.

Assim, passamos de 2 a 2,5 horas para concluir a tarefa com a certeza de que tudo vai correr bem, sem efeitos colaterais não desejados ou confusão no trabalho do usuário.

Parte 2. Como posso reduzir esse tempo?


Infelizmente, o único resultado desses esforços é apenas o cumprimento da tarefa. Isso não é o ideal, o que é muito decepcionante. O conhecimento adquirido pelo desenvolvedor no decorrer do trabalho é pessoal e efêmero. Se outro desenvolvedor (ou a nós mesmos após 6 meses) precisar novamente fazer alterações nessa parte do código, o processo precisará ser repetido.

Existem duas táticas principais para remediar a situação:

  1. Limpe ativamente a base de código para reduzir a duplicação e a complexidade.
  2. Escreva testes automatizados.

Nota: já discutimos a documentação, mas, neste caso, essa não é a melhor solução. A documentação é útil para idéias de alto nível, como explicar a lógica comercial ou processos repetidos com frequência, como uma lista de novos parceiros. Mas quando se trata de código, a documentação rapidamente se torna muito volumosa e desatualizada à medida que o código muda.

Você notou que nenhuma dessas táticas está incluída em nossas 2 a 2,5 horas.

Por exemplo, manter uma base de código limpa significa que, em vez de simplesmente concluir a tarefa, fazemos perguntas:

  • Por que existem tantas maneiras diferentes de identificar tarefas cujo prazo se aproximou / expirou?
  • Todos eles precisam e trabalham neles?
  • Esses métodos podem ser reduzidos a um ou dois conceitos / métodos?
  • Se o conceito for dividido entre o antigo e o novo, ele pode ser consolidado?

E assim por diante

As respostas para essas perguntas podem ser bastante rápidas: por exemplo, se encontrarmos um código claramente morto. Ou eles podem levar várias horas: por exemplo, se tarefas forem usadas em muitos processos complexos. Assim que tivermos essas respostas, a refatoração levará ainda mais tempo para reduzir a duplicação / confusão e obter uma única descrição do conceito de "prazo" - ou renomeie os conceitos no código para entender claramente como eles diferem e por que.

Mas, no final, essa parte da base de código se tornará muito mais simples, será mais fácil ler e modificar.

Outra tática que costumamos usar é o teste automatizado. Em certo sentido, os testes automatizados são semelhantes à documentação que não pode ser desatualizada e que é mais fácil de detectar. Em vez de executar manualmente o código e visualizar a saída, escrevemos um código de teste que inicia a solicitação e verifica a saída programaticamente. Qualquer desenvolvedor pode executar esse código de teste para entender como o sistema deve funcionar e para garantir que ele ainda funcione dessa maneira.

Se você tiver um sistema com cobertura de teste decente, essas alterações levarão significativamente menos tempo. Você pode alterar a lógica e, em seguida, executar o conjunto de testes completo e garantir que

  1. a mudança funciona corretamente;
  2. a mudança não quebrou nada (essa é uma informação ainda mais valiosa do que no primeiro parágrafo).

Quando construímos sistemas do zero no Simple Thread, sempre incluímos tempo para escrever testes automatizados na avaliação de prazos. Isso pode retardar o desenvolvimento inicial, mas melhora muito a eficiência do trabalho e da manutenção. Somente quando o sistema cresce, você realmente entende a importância dos testes, mas neste momento pode ser muito difícil retornar os testes ao sistema. A presença de testes também simplifica bastante o trabalho de novos funcionários e a alteração do comportamento do sistema é muito mais rápida e segura.

Parte 3. De onde viemos? Para onde vamos?


Hoje, raramente indicamos em sua avaliação o tempo para limpar o código ou escrever testes. Isso ocorre em parte porque escrever testes a partir do zero é uma sobrecarga menor, e adicionar testes à data anterior da base de código é muito trabalhoso, como restaurar a base sob a casa em que as pessoas vivem.

Isso também se deve em parte ao fato de que, começando a trabalhar com você, mudamos imediatamente para o modo de ressuscitação. Temos problemas quase diários com a sincronização de dados de terceiros, problemas semanais com a geração de relatórios, solicitações constantes para suportar pequenas alterações de dados, monitoramento e log do sistema inadequados etc. A base de códigos está se afogando com o peso de dívidas técnicas e estamos tentando febrilmente manter os sistemas flutuar, enquanto fura buracos com fita isolante.

Com o tempo, os sistemas se tornam mais estáveis ​​e confiáveis, automatizamos / fornecemos a interface do usuário para autoatendimento de solicitações de suporte frequentes. Ainda temos muitas dívidas técnicas, mas saímos do modo de emergência. Mas não acho que nos afastaremos completamente dessa mentalidade de ressuscitação para uma mentalidade mais proativa e madura de "planejar e executar".

Tentamos limpar o código em qualquer lugar e sempre testamos minuciosamente. Mas ser cuidadoso e diligente não é refatoração proativa ou criar a infraestrutura necessária para bons testes automatizados.

Se não começarmos a pagar algumas dívidas técnicas, nunca conseguiremos melhorar significativamente a situação. Desenvolvedores competentes e altamente qualificados levarão meses para navegar e fazer alterações não triviais.

Em outras palavras, 4-8 horas para esta tarefa são cerca de 2-4 vezes o suprimento, mas reduzirão significativamente os esforços para essas mudanças no futuro. Se essa parte da base de código fosse mais limpa e tivesse uma boa cobertura com testes automáticos, um desenvolvedor experiente e competente a concluiria em uma hora ou menos. E o ponto principal é que o novo desenvolvedor levará um pouco mais de tempo.

Para tal alteração nos termos, precisamos do seu consentimento. Esta é uma tentativa consciente de melhorar fundamentalmente o desempenho do seu sistema, não apenas a percepção dos usuários. Entendo que é difícil concordar com esses investimentos precisamente porque não há benefício visível, mas estamos felizes em sentar com você e preparar alguns números claros que mostrarão como esses investimentos serão recompensados ​​a longo prazo do ponto de vista da engenharia.

Obrigada
Al

Source: https://habr.com/ru/post/pt451560/


All Articles