Não concorde em desenvolver algo que você não entende

Não concorde em desenvolver algo que você não entende

Desde o início de 2018, ocupo o cargo de líder/chefe/desenvolvedor líder na equipe - chame como quiser, mas a questão é que sou inteiramente responsável por um dos módulos e por todos os desenvolvedores que trabalham nele. Esta posição me dá uma nova perspectiva sobre o processo de desenvolvimento, pois estou envolvido em mais projetos e mais ativamente envolvido na tomada de decisões. Recentemente, graças a essas duas coisas, de repente percebi o quanto a medida de compreensão afeta o código e a aplicação.

O que quero ressaltar é que a qualidade do código (e do produto final) está intimamente relacionada ao quão conscientes as pessoas que estão projetando e escrevendo o código estão sobre o que estão fazendo.

Você pode estar pensando agora: “Obrigado, capitão. Claro, seria bom entender o que você está escrevendo em geral. Caso contrário, você também pode contratar um grupo de macacos para pressionar teclas arbitrárias e deixar por isso mesmo.” E você está absolutamente certo. Conseqüentemente, presumo que você perceba que é necessário ter uma ideia geral do que está fazendo. Isso pode ser chamado de nível zero de compreensão e não iremos analisá-lo em detalhes. Veremos em detalhes o que exatamente você precisa entender e como isso afeta as decisões que você toma todos os dias. Se eu soubesse dessas coisas com antecedência, teria me poupado muito tempo perdido e códigos questionáveis.

Embora você não veja uma única linha de código abaixo, ainda acredito que tudo o que foi dito aqui é de grande importância para escrever código expressivo e de alta qualidade.

Primeiro nível de compreensão: Por que não funciona?

Os desenvolvedores geralmente atingem esse nível muito cedo em suas carreiras, às vezes até sem qualquer ajuda de terceiros – pelo menos na minha experiência. Imagine que você recebeu um relatório de bug: alguma função do aplicativo não funciona, precisa ser corrigida. Como você procederá?

O esquema padrão é assim:

  1. Encontre o trecho de código que está causando o problema (como fazer isso é um tópico separado, eu abordo isso em meu livro sobre código legado)
  2. Faça alterações neste snippet
  3. Certifique-se de que o bug foi corrigido e que nenhum erro de regressão ocorreu

Agora vamos nos concentrar no segundo ponto - fazer alterações no código. Existem duas abordagens para esse processo. A primeira é investigar exatamente o que está acontecendo no código atual, identificar o erro e corrigi-lo. Segundo: mova-se pelo sentimento - adicione, digamos, +1 a uma instrução ou loop condicional, veja se a função funciona no cenário desejado, depois tente outra coisa e assim por diante, ad infinitum.

A primeira abordagem está correta. Como Steve McConnell explica em seu livro Code Complete (que eu recomendo fortemente, aliás), toda vez que alteramos algo no código, devemos ser capazes de prever com confiança como isso afetará a aplicação. Estou citando de memória, mas se uma correção de bug não funcionar da maneira que você esperava, você deverá ficar muito alarmado e questionar todo o seu plano de ação.

Para resumir o que foi dito, para realizar uma boa correção de bug que não prejudique a qualidade do código, é necessário entender toda a estrutura do código e a origem do problema específico.

Segundo nível de compreensão: Por que funciona?

Este nível é compreendido de forma muito menos intuitiva que o anterior. Eu, ainda um desenvolvedor novato, aprendi graças ao meu chefe e, posteriormente, expliquei repetidamente a essência do assunto aos recém-chegados.

Desta vez, vamos imaginar que você recebeu dois relatórios de bugs de uma vez: o primeiro é sobre o cenário A, o segundo é sobre o cenário B. Em ambos os cenários, algo errado acontece. Conseqüentemente, você resolve o primeiro bug primeiro. Usando os princípios que desenvolvemos para compreensão do Nível XNUMX, você se aprofunda no código relevante para o problema, descobre por que ele faz com que o aplicativo se comporte da maneira que se comporta no Cenário A e faz ajustes razoáveis ​​que produzem o resultado esperado. . Tudo está indo muito bem.

Então você passa para o cenário B. Você repete o cenário na tentativa de provocar um erro, mas – surpresa! - agora tudo funciona como deveria. Para confirmar seu palpite, você desfaz as alterações feitas enquanto trabalhava no bug A e o bug B volta. Sua correção de bug resolveu os dois problemas. Sortudo!

Você não contava com isso. Você descobriu uma maneira de corrigir o erro no cenário A e não tem ideia de por que funcionou no cenário B. Neste estágio, é muito tentador pensar que ambas as tarefas foram concluídas com êxito. Isso é bastante lógico: o objetivo era eliminar erros, não era? Mas o trabalho ainda não terminou: você ainda precisa descobrir por que suas ações corrigiram o erro no cenário B. Por quê? Porque pode estar trabalhando com princípios errados e então você precisará procurar outra saída. Aqui estão alguns exemplos de tais casos:

  • Como a solução não foi adaptada ao erro B, levando em consideração todos os fatores, você pode ter quebrado a função C sem saber.
  • É possível que exista também um terceiro bug escondido em algum lugar, relacionado à mesma função, e sua correção de bug dependa dele para o correto funcionamento do sistema no cenário B. Tudo parece bem agora, mas um dia esse terceiro bug será percebido e corrigido. Então, no cenário B, o erro ocorrerá novamente, e é bom, mesmo que exista.

Tudo isso adiciona caos ao código e um dia cairá na sua cabeça - provavelmente no momento mais inoportuno. Você terá que reunir sua força de vontade para se forçar a gastar tempo entendendo por que tudo parece funcionar, mas vale a pena.

Terceiro nível de compreensão: Por que funciona?

A minha visão recente refere-se precisamente a este nível, e é provavelmente aquele que me teria dado mais benefícios se tivesse chegado a esta ideia mais cedo.

Para deixar mais claro, vejamos um exemplo: seu módulo precisa ser compatível com a função X. Você não está particularmente familiarizado com a função X, mas lhe disseram que para ser compatível com ela você precisa usar o framework F. Outros módulos que se integram ao X funcionam exatamente com ele.

Seu código não esteve em contato com o framework F desde o primeiro dia de sua vida, portanto implementá-lo não será tão fácil. Isto terá consequências graves para algumas partes do módulo. No entanto, você se dedica ao desenvolvimento: passa semanas escrevendo código, testando, lançando versões piloto, obtendo feedback, corrigindo erros de regressão, descobrindo complicações imprevistas, não cumprindo os prazos originalmente acordados, escrevendo mais código, testando, obtendo comunicação de feedback, corrigindo erros de regressão - tudo isso para implementar a estrutura F.

E em algum momento você de repente percebe - ou talvez ouça de alguém - que talvez o framework F não lhe dê nenhuma compatibilidade com o recurso X. Talvez todo esse tempo e esforço tenham sido investidos de forma completamente errada nisso.

Algo semelhante aconteceu uma vez enquanto trabalhava em um projeto pelo qual eu era responsável. Por quê isso aconteceu? Porque eu tinha pouco entendimento do que era a função X e como ela se relacionava com a estrutura F. O que eu deveria ter feito? Peça à pessoa que atribui a tarefa de desenvolvimento para explicar claramente como o curso de ação pretendido leva ao resultado desejado, em vez de simplesmente repetir o que foi feito para outros módulos ou acreditar na sua palavra de que é isso que o recurso X precisa fazer.

A experiência deste projeto me ensinou a recusar iniciar o processo de desenvolvimento até que tenhamos uma compreensão clara do motivo pelo qual estamos sendo solicitados a fazer certas coisas. Recuse imediatamente. Ao receber uma tarefa, o primeiro impulso é assumi-la imediatamente para não perder tempo. Mas a política de “congelar o projecto até entrarmos em todos os detalhes” pode reduzir o desperdício de tempo em ordens de grandeza.

Mesmo que tentem te pressionar, te obrigar a começar a trabalhar, mesmo que você não entenda o porquê disso, resista. Primeiro, descubra por que você está recebendo tal tarefa e decida se esse é o caminho certo para atingir o objetivo. Tive que aprender tudo isso da maneira mais difícil - espero que meu exemplo facilite a vida de quem lê isto.

Quarto nível de compreensão: ???

Sempre há mais para aprender em programação e acredito que apenas arranhei a superfície do tópico da compreensão. Que outros níveis de compreensão você descobriu ao longo dos anos trabalhando com código? Que decisões você tomou que tiveram um impacto positivo na qualidade do código e da aplicação? Que decisões se revelaram erradas e lhe ensinaram uma lição valiosa? Compartilhe sua experiência nos comentários.

Fonte: habr.com

Adicionar um comentário