
Olá Habr!
Não há fim em falar sobre
código limpo , mas o próximo artigo de Dave Nicoletta é muito metafórico e, espero, realmente digno de tradução. Que seja um pouco "edificante", como o autor avisa os leitores com antecedência no artigo original.
Boa leitura.
Em casa, ao longo dos anos, um mau hábito se estabeleceu. Usando qualquer ferramenta, esquecemos de colocá-la em seu lugar. Na próxima vez que alguém precisou, eles tiveram que gastar mais tempo procurando uma ferramenta do que resolvendo um problema. O mais triste é que mesmo quem pegou o instrumento por último e o jogou em qualquer lugar estava condenado às mesmas buscas. Frequentemente, era mais rápido comprar novos equipamentos do que procurar a ferramenta que possuímos - sabemos com certeza! - em algum lugar por aí.
Portanto, temos quatro chaves de fenda Phillips de tamanho médio da Philips, três com um slot chato, um monte de pinças e chaves extras, conjuntos de adaptadores. Sem mencionar a impressionante coleção de canetas, novelos de fita, baterias e outras coisas boas espalhadas por toda parte.
Uma vez que decidimos: basta! Alocamos seu lugar para todas as coisas e colocamos as coisas em ordem com nosso inventário. Ferramentas entregues doadas à caridade. Fizemos todos os esforços para cultivar a autodisciplina e sempre colocamos as ferramentas apenas em seu lugar depois de trabalharmos com elas. A qualidade e o volume de trabalho por unidade de tempo aumentaram bastante. O estresse, o dinheiro desperdiçado e o humor estragado se tornaram muito menos.
Colocar ordem na garagem corporativa
E se os mecânicos de automóveis que trabalham em uma garagem corporativa largassem ferramentas em qualquer lugar? Eles passavam mais tempo procurando ferramentas do que realmente trabalhando. Os detalhes seriam colocados no lugar errado, perdidos, enferrujados, estragados, seriam simplesmente roubados. Os custos de fornecimento aumentariam bastante.
Levaria mais tempo para concluir as tarefas, mas a qualidade do trabalho diminuiria. Quando um mecânico precisa trabalhar com ferramentas enferrujadas, desgastadas e quebradas, é difícil para ele encaixar e prender as peças adequadamente. Além disso, o hábito de arrumar uma bagunça na oficina afetará inevitavelmente a qualidade do trabalho.
Os clientes estarão fartos de transferências intermináveis de trabalhos finais. Em breve eles irão para oficinas mais confiáveis. De alguma forma, sem você. Talvez as analogias com o desenvolvimento e suporte de software já sejam óbvias.
Colocando ordem no desenvolvimento de software
Vejamos um exemplo específico: refatoração incremental.
Essa expressão é intrigante para muitos. Não sei qual palavra os confunde: "incremental" ou "refatoração".
A refatoração incremental (gradual) é fundamentalmente diferente da grande escala. Parece para muitos que qualquer refatoração é necessariamente "em larga escala", que deve ser "autorizada" por alguém e, portanto, supostamente, o trabalho deve ser arrastado. De fato, se negligenciar a refatoração no decorrer do trabalho, tudo será atrasado significativamente.
A maioria dos treinadores técnicos, inclusive eu, dificilmente explica a diferença neste caso; não porque essa diferença seja por definição complicada, mas porque é realmente difícil formular em palavras. No entanto, acho que o hábito de considerar cuidadosamente o estoque disponível e monitorar o suprimento é uma boa analogia nesse caso.
Refatoração gradual
Fazer refatoração gradual é como manter a ordem em uma bancada de trabalho, mesmo no auge do trabalho. Usou uma chave de fenda - coloque-a no lugar. Antes de cada nova tarefa, não reconstruiremos um workshop para isso. O ponto, ao contrário, é a capacidade de terminar ... como terminar o que você começou. Despir as pontas.
A refatoração gradual não leva muito tempo extra e não requer a permissão de alguém de cima. Nesse caso, você precisa pedir permissão para não limpar o código, se precisar se apressar. A capacidade de manter constantemente o código limpo deve de fato ser considerada a habilidade profissional básica de um programador. É uma pena que hoje, o "código limpo" precise de propaganda, e alguns programadores se opõem a trazer tanta pureza. A refatoração gradual não tem absolutamente nada com a refatoração arquitetônica em larga escala, o que realmente requer um planejamento cuidadoso, alocando tempo, dinheiro e pessoas para isso.
Regra de escoteiro
Na programação, existe a chamada "regra de reconhecimento": mantenha o código pelo menos tão limpo quanto foi recebido. O mesmo se aplica ao armazenamento de ferramentas de trabalho em casa. Se estivermos procurando um alicate, mas observe que a chave de fenda acidentalmente entrou na cruz e a chave de fenda cruzou na fenda, nós, no processo, colocamos no lugar. Não precisamos de aprovação oficial para fazer isso.
É assim que a refatoração gradual funciona. Antes de nós existe um pedaço de código, e precisamos adicionar uma nova condição à lista de construções disponíveis. Percebemos que a lista é implementada como um grande bloco if / else. Decidimos que ele precisa ser reprojetado como um comutador ou um operador de seleção, enquanto adiciona uma condição. Pode-se argumentar: isso é realmente muito melhor do que o bloco if / else? Sim, você está certo: não muito. Mas um pouco melhor. Quando alguém ler este código depois de você, ele poderá refiná-lo ainda melhor, pois você melhorou sua posição inicial. Se você já fez algo assim antes, provavelmente percebeu que, lendo cuidadosamente todas as condições, às vezes encontrava construções duplicadas, e então a ordem não ideal de expressões; talvez você tenha encontrado alguma condição que nunca pode ser cumprida, ou mesmo um “buraco” lógico pelo qual toda a sequência de controle cairá no bloco if / else, e alguns casos não serão processados. Apenas regozije-se que você o descobriu agora, e não tarde da noite, ao receber um ticket correspondente do serviço de suporte técnico. Nesse momento em que os olhos se unem, não há absolutamente nenhum desejo de entender o código confuso.
Talvez adicionaremos alguma nova funcionalidade ao aplicativo e notamos que a função / método que escrevemos é muito semelhante a outra (outra) que já temos na base de código. Depois de passar apenas alguns segundos, vamos nos livrar dessa duplicação, mesmo sem as ferramentas adicionais oferecidas em nossos serviços nos IDEs chiques. Você pode refatorar sem hesitar, pois nos acostumamos à autodisciplina e garantimos que os microtestes (testes de unidade) que cobrem este caso já foram escritos. Então a refatoração manual não é terrível. No final, invente pelo menos uma razão para não?
“Longo prazo” geralmente não é tão longo quanto parece
Frequentemente, ouço de pessoas diferentes que a refatoração traz benefícios de "longo prazo". Embora, em teoria, seja aqui, no mundo real, você precise constantemente entregar o trabalho em termos estritos. No entanto, se falarmos sobre manter a pureza do código por meio de uma pequena refatoração gradual, o "longo prazo" dura exatamente até o momento em que alguém toca na base de código. Exatamente até a próxima.
A má notícia é que o oposto é verdadeiro. Se você não limpar o código enquanto trabalha, ele se deteriora rapidamente. Não temos um "airbag" de dez anos que nos permita acumular impunidade até que os problemas comecem. A próxima mudança que precisará ser feita levará um tempo inaceitavelmente longo, o risco de regressão do código aumentará e a situação sem a devida atenção apenas piorará.
Se estivermos hackeando apenas para satisfazer o desejo do cliente (e ele desejar o produto acabado mais rapidamente), como continuaremos atendendo a essas solicitações depois de garantir que nenhuma alteração rápida seja feita mais, desde que trouxemos o código ao estado confusão, e é impossível mantê-lo?
O que é rápido, o que é lento?
Os clientes sempre querem que você trabalhe mais, independentemente da velocidade da sua organização. A maneira mais eficaz de reduzir o tempo de lançamento é fazer tudo certo; fazer bem; Limpe constantemente as extremidades, sempre, sem exceção. Cortando os cantos para “acelerar”, na prática, apenas diminuímos a velocidade, e não na efêmera “perspectiva de longo prazo”, mas aqui e agora.
Quando o cliente exige que você trabalhe mais rápido, isso não significa que ele permite que você trabalhe sem cuidado. Naturalmente, parece óbvio para ele que, após cada solicitação, não deve nos lembrar que ele está interessado em alta qualidade. A alta qualidade está implícita como um dos componentes do nosso trabalho.
Como engenheiros, nós mesmos escolhemos considerar a refatoração gradual como o elemento básico de nossa atividade profissional. Não perguntamos se podemos trabalhar como deveria, assim como o cirurgião não pergunta ao contador se ele tem tempo para lavar as mãos antes da operação. O tempo gasto na operação é exatamente o tempo necessário para que a operação seja bem-sucedida. O paciente precisa ser cuidadosamente removido do apêndice e, após a alta, a pessoa pode retornar à vida normal - sem infecção da ferida e sem tampão no abdômen. Isso só piorará se uma pessoa for retirada da sala de cirurgia dez minutos antes do necessário e, em seguida, as complicações começarem.
Freqüentemente, nesse caso, eles defendem que, se "tudo é feito de acordo com a ciência", acaba sendo "muito longo". De fato, “muito tempo” é o tempo que leva para corrigir as consequências se o trabalho foi feito às pressas e sem o profissionalismo adequado. A recuperação da infecção é um choque real para o paciente e sua família; isso inevitavelmente afetará seu trabalho. Uma segunda operação, na qual um tampão esquecido deve ser cortado do abdômen, é uma intervenção muito mais séria, e será necessária apenas porque a pessoa foi operada com pressa pela primeira vez.
Ao programar, se você precisar fazer cinco regressões do código devido ao fato de alguém ter escrito com pressa, não é possível falar em "economia de tempo". Pelo contrário, as alterações são feitas por mais tempo. O trabalho não é "concluído" até que seja feito corretamente. Se a equipe tiver que gastar horas e dias corrigindo erros após a "preparação para o rascunho", isso significa tempo perdido que poderia ser gasto em outro trabalho útil. Este é um lucro perdido.
Tais erros causam consequências semelhantes às ondas e levam a perdas de tempo e dinheiro a longo prazo e, às vezes, à perda de clientes. Um estresse adicional recai sobre os ombros dos próprios engenheiros; moral baixa, alta rotatividade de pessoal. Por isso, um parafuso cada vez mais difícil e uma diminuição ainda maior da moralidade e do envolvimento no trabalho.
Dívida técnica como metáfora
Sempre que você se voltar para o tema da refatoração gradual, alguém o lembrará definitivamente da dívida técnica. Eles dirão: "Temos um prazo tão longo que é necessário apenas cortar custos". Acrescentarão que, nesse caso, a equipe acumula conscientemente dívidas técnicas, guiadas pelas necessidades do negócio.
Aqueles que dizem isso não entendem essa metáfora, e talvez nenhuma metáfora.
A metáfora não pretende ser uma descrição completa e abrangente da coisa que está sendo caracterizada.
Uma metáfora ajuda em geral a esboçar uma impressão de um aspecto dessa coisa.
As pessoas tendem a substituir uma coisa por sua metáfora e depois operam com uma metáfora como se ela e
o descrito é uma e a mesma coisa. Não, isso não é a mesma coisa. O ponto.
Além disso, é comum as pessoas interpretarem amplamente uma metáfora além do seu contexto original. Assim, o significado da metáfora é obscurecido e se torna cada vez menos útil.
Ward Cunningham propôs uma metáfora para a dívida técnica, descrevendo as interações com os clientes no setor financeiro. Ele procurou uma metáfora adequada para esse contexto específico, para enfatizar como a realização gradual de oportunidades ajuda a criar um ciclo de feedback durante o qual o programa é constantemente otimizado. Ele não quis dizer "cortar custos para criar a ilusão de desenvolvimento rápido".
O conceito original da metáfora da dívida técnica implicava que o código era necessariamente mantido limpo. As pessoas que entendem o problema deixado no código avançam passo a passo em direção à sua solução, e o código sempre será preciso o suficiente para que tais melhorias graduais possam ser feitas. Não é uma questão de que algumas razões técnicas possam justificar por que o código é indesejável e requer correções constantes.
Cortar os cantos para entregar rapidamente o trabalho não é um acúmulo de dívida técnica. Este é um truque comum.
Quem é responsável?
Para obter uma entrega rápida, você precisa se livrar dos problemas ao trabalhar. Um desses problemas é o código não solicitado. Você pode se livrar desse obstáculo passo a passo aprendendo a trabalhar a autodisciplina. Nesse caso, não importa como você trabalha - de acordo com o modelo "cascata" ou com o "aggail". Nós mesmos escolhemos como trabalhar sempre que tocamos no teclado.
Eu resumo. Se você trabalhar corretamente, incluindo a limpeza das extremidades, beneficiará apenas o cliente, patrocinadores, gerentes, aqueles que apoiarão nosso código no futuro e, é claro, para nós mesmos.