Em algum momento, um programa está em desenvolvimento. Os recursos estão sendo adicionados, removidos ou alterados o tempo todo. Toda versão não passa de um protótipo. Portanto, não perco muito tempo escrevendo código super limpo nesse momento, porque nunca sei quanto tempo algo dura. É claro que tento manter a qualidade do código em certos padrões, mas o tempo é sempre um problema.
Depois, chega o momento em que o programa termina e o (s) tomador (es) de decisão diz "é isso aí". Eu tenho um protótipo funcional neste momento, mas o código interno é um pouco confuso de todas as partes durante a fase de desenvolvimento. Espera-se que eu comece o teste / depuração final, mas meu instinto diz que agora devo de alguma forma limpar e / ou reescrever as coisas para fornecer uma arquitetura adequada que facilite a manutenção, etc.
Depois que o material é testado e aprovado, não faz sentido reescrevê-lo. Em uma base regular, eu permaneço lá com um protótipo 'pronto' em funcionamento e recebo um erro durante o teste e vejo que é o resultado de uma codificação não inteligente que é o resultado de todo o processo de desenvolvimento. Estou no meio de testes e a correção seria uma reescrita ... está uma bagunça!
Existem maneiras melhores / manuais, tenho certeza. Mas eu tenho que trabalhar em um ambiente de trabalho real, onde nem tudo é livro.
Então, como faço a transição do meu protótipo de trabalho para uma versão de lançamento com uma base de código estável? Talvez eu não deva considerar o desenvolvimento concluído assim que o fizer e realmente o vejo como a fase de limpeza ... Não sei, preciso de ajuda aqui.
EDITAR
Eu quero esclarecer algumas coisas.
Estou 100% do lado de fazê-lo logo antes e não depois, código limpo e legível. Mas eu também tenho que fazer as coisas e não consigo sonhar com a beleza do código, tudo limpo e brilhante. Eu tenho que encontrar um compromisso.
frequentemente, um novo recurso é realmente apenas algo que queremos experimentar e ver se faz sentido implementar algo assim. (especialmente em aplicativos móveis, para obter uma aparência real em um dispositivo real) Portanto, é algo pequeno que (imho) não justifica muito trabalho em uma primeira iteração "vamos ver". No entanto, às vezes, surge a questão QUANDO pago esta dívida técnica? É disso que se trata esta questão.
Se eu souber que metade dos recursos serão descartados um dia depois (já temos experiência suficiente em nossa empresa), acho realmente difícil acreditar que a melhor maneira de abordar meu problema é, no entanto, investir tempo extra para escrever tudo limpo, mesmo que a maior parte será descartada logo depois. Parece-me que economizarei tempo se fizer uma grande limpeza quando a coisa estiver sólida, daí a minha pergunta.
fonte
Respostas:
Não saber quanto tempo dura algo nunca deve ser uma desculpa para negligência - muito pelo contrário. O código mais limpo é o IMHO, aquele que não entra no seu caminho quando você precisa alterar alguma coisa. Portanto, minha recomendação é: sempre tente escrever o código mais limpo possível - especialmente ao codificar um protótipo. Porque será muito mais fácil adaptá-lo quando algo tiver que ser alterado (o que certamente acontecerá).
Não me interpretem mal - minha compreensão do "código mais limpo" não tem nada a ver com tornar o código bonito por uma questão de beleza. Isso é realmente algo que pode atrasá-lo. No meu ponto de vista, o código limpo é um código que é autoexplicativo (não há necessidade de escrever tantos documentos - causa aceleração), fácil de entender (menos erros, menos necessidade de depuração - aceleração, menos tempo necessário para encontrar a solução correta). lugar para alterar - aceleração), resolve o problema fornecido com a menor quantidade de código necessário (menos código para depuração - aceleração óbvia), é SECO (apenas um lugar para mudar quando algo precisa ser alterado - aceleração - e menos risco de introdução novos bugs esquecendo de mudar um segundo lugar), segue os padrões de codificação (coisas menos complicadas para se pensar - aceleração), usa pequenos,
Fazer "limpeza" depois nunca funciona. Considere a limpeza antes de implementar um novo recurso ou quando começar a implementá-lo, mas não depois. Por exemplo, sempre que você começar a tocar em um método para um recurso e perceber que ele tem mais de 10 linhas, considere refatorá-lo para métodos menores - imediatamente , antes de concluir o recurso. Sempre que você detecta uma variável ou nome de função existente, não sabe exatamente o que isso significa, descubra para que serve e renomeie a coisa antes de fazer qualquer outra coisa. Se você fizer isso regularmente, mantenha seu código pelo menos em um estado "suficientemente limpo". E você começa a economizar tempo - porque precisa de muito menos tempo para depuração.
... que é a prova real do que escrevi acima: estar "sujo" assombra imediatamente quando você começa a depurar seu código e o torna mais lento.
Você pode evitar isso quase completamente se fizer a limpeza imediatamente. Em seguida, as correções de bugs significarão pequenas alterações no código, mas nunca uma grande alteração na arquitetura. Se você realmente detectar evidências de um aprimoramento da arquitetura durante o teste, adie-o, coloque-o no seu sistema de rastreamento de problemas e implemente-o na próxima vez em que precisar implementar um recurso que beneficia dessa alteração ( antes de começar com esse recurso).
Isso requer alguma disciplina e alguma experiência em codificação, é claro. É uma idéia semelhante à idéia por trás do "desenvolvimento orientado a testes", fazer essas coisas antes, em vez de fazê-las depois (o TDD também pode ajudar, mas o que eu escrevi funciona mesmo quando você não usa o TDD). Quando você faz isso consequentemente, não precisará de nenhuma "fase de limpeza" especial antes de liberar.
fonte
Você tem dois problemas separados, ambos com o mesmo sintoma (código incorreto):
Problema nº 1: Controle insuficiente de requisitos Não quero dizer que suas partes interessadas os alterem com muita frequência, mas você está permitindo alterações nos requisitos durante um ciclo de correção / teste de bug. Mesmo as metodologias ágeis não suportam isso; você constrói, você testa, entrega, injeta novos requisitos.
Problema 2: Você acredita que o que está escrevendo é "apenas por agora" No código do desenvolvimento de software "por agora" é realmente extremamente raro. Você percebeu que, depois de atender a um requisito do usuário, os rigores da oferta e da demanda dificultam a justificação de voltar e reimplementar um recurso "pronto". Então o que fazer sobre isso? Sempre escreva o código de produção. Funcionalmente para você, isso significa que suas estimativas para as partes interessadas precisam ser substancialmente maiores, para que você tenha tempo para fazer o que é certo.
Além disso, entenda que você está trabalhando na posição mais difícil como desenvolvedor: leia a opinião de Joel Spolsky sobre a vida de um desenvolvedor interno . Então, você precisa ser extremamente vigilante se quiser manter sua sanidade intacta.
fonte
É um problema comum - especialmente ao criar o que é essencialmente um balão de teste de software , por assim dizer.
Existem várias abordagens que podem ajudar. Em primeiro lugar, a abordagem TDD pode ajudar a reduzir a base de código à estritamente necessária. Se seus testes andam de mãos dadas com seu código, você pode pelo menos ter alguma certeza de que seu código se comporta como deveria.
Tire um tempo para refatorar à medida que avança. Uma vez que você tenha um protótipo e o cliente esteja ansioso para colocar as mãos nele, é uma venda difícil dizer que você precisa de tempo para polir o que (para eles) está completo. Eu gosto de fazer check-in diariamente, seguido de um refator, mas YMMV.
Os desenvolvedores que escrevem código rapidamente são frequentemente requisitados - tivemos um desenvolvedor desse tipo no meu último departamento. Todo time o queria porque ele trabalhava super rápido. Porém, quando chegou a hora de testar e liberar seu código, as rodas rapidamente se soltaram. Coisas codificadas, hacks e atalhos em todos os lugares. Suas ações logo caíram - maciçamente.
Cortar o código de produção desde o início pode parecer uma chatice, mas dependendo do seu ambiente, existem muitas ferramentas que podem facilitar o desenvolvimento, como o Ghostdoc e o Stylecop .
Vale a pena entrar na mentalidade de desenvolvimento correta desde o início. Você ficaria surpreso com a quantidade de sistemas de pacote de cigarros que deveriam ser apenas soluções de abertura de lacunas que se tornam aplicativos de base.
fonte
Continuamente
A velocidade do desenvolvimento é o principal motivo para escrever um código limpo, legível e testável; não é feito pela beleza, nem por outros valores abstratos. Por que eu negaria isso a mim mesmo e só o faria depois para algum programador futuro?
Claro que pode haver mudanças que são principalmente cosméticas e, portanto, não essenciais; Eu diria que é muito mais útil ter um código moderadamente bom agora, durante o desenvolvimento, do que ter uma bagunça agora e esperar torná-lo perfeito mais tarde (o que, vamos encarar, isso nunca vai acontecer, mesmo se você tivesse A Hora).
fonte
Você faz isso diferenciando entre o código "Estou apenas tentando isso para ver como funciona" e o código "isso está direcionado para o produto". Existem várias maneiras de fazer isso.
Um deles é ramificado ou qualquer que seja a palavra em seu sistema de controle de origem. Você cria uma ramificação para o novo relatório ou o novo layout de importação ou o que for. Se as pessoas gostarem, o trabalho de devolvê-lo à ramificação principal é um trabalho rastreável e separado. Ele pode ser atribuído a alguém e relatado e não se espera que aconteça magicamente no dia em que o gerenciamento (ou vendas) concorda que o recurso pertence ao produto.
Outro são picos. Você não faz essa alteração no produto. Você entra em algum aplicativo separado, super simples, que existe apenas para você ter um lugar para colocar código. Você pode ser tão confuso quanto quiser, porque está apenas explorando a nova API ou o que quer. E, novamente, se você voltar e informar "sim, nós podemos fazer isso, eu descobri como" existe uma tarefa rastreável, reportável e atribuível de escrever código pronto para o produto para fazer o que você deseja.
Nos dois casos, pronto para o produto significa legível, limpo, seguindo os padrões de nomenclatura, com testes e aderindo ao seu estilo de código e metas de desempenho. Nos dois casos, você torna esse trabalho visível. Concordo que você não deseja fazer todo esse trabalho toda vez que alguém provavelmente retira o recurso do produto. Mas você também não quer deixar esse trabalho invisível. Trabalhar em cópias separadas do produto ou em um produto não relacionado que seja pouco mais do que um equipamento de teste permite que você aplique o trabalho para criar um código pronto para o produto assim que alguém decidir que deseja algo.
A desvantagem é que eles não podem decidir que desejam algo e enviá-lo (ou seja, a meia-versão meia-boca, bagunçada, não testada, não documentada e possivelmente lenta, que você implementou como prova de conceito) amanhã. Na primeira vez em que você se opõe a essa questão, basta perguntar se você deve fazê-lo da maneira mais longa (mais cara) todas as vezes, diminuindo o caminho para recursos rejeitados. Se você perguntar corretamente, você receberá um "não".
fonte
Realmente acho que você já entende o problema. O problema é que seu estilo de codificação exige que você faça muito retrabalho. O motivo pelo qual é necessário muito retrabalho é que: (a) ele é acompanhado de previsão e planejamento insuficientes; e (b) os patches incrementais de curto prazo regularmente colocados durante o desenvolvimento aumentam combinatoriamente a complexidade de qualquer retrabalho necessário.
A resposta, portanto, é
(a) mude seu estilo de desenvolvimento um pouco mais para o cascata e um pouco menos ágil. Não vá até o fim, porque a cachoeira clássica tem suas próprias armadilhas. Há um equilíbrio saudável a ser tido. Eu sei que pode ser preocupante apenas pensar nas coisas por alguns dias, às vezes, como se nenhum desenvolvimento estivesse sendo feito, mas você precisa confiar no processo. Na engenharia, você não pode simplesmente unir as coisas e depois unir as coisas por cima e esperar ter uma solução elegante. Se não há ninguém fazendo arquitetura e design técnico de nível superior, isso significa que é seu trabalho. Você está pagando o preço de negligenciar esse trabalho.
(b) tente evitar consertar as coisas. Não pense a longo prazo apenas quando chegar a hora de fazer o controle de qualidade. Realmente, você deve testar cada pedacinho que constrói, o tempo todo, e cobrindo todos os casos de entrada, aqueles que não estão no caminho feliz também. Um patch / hack é quase por definição uma correção de curto prazo, que pode muito bem ter um custo de longo prazo, atinge o Custo Total de Propriedade do cliente no sistema. Novamente, a pressão está alta para liberar o código, então é preciso haver equilíbrio. Mas tente não implementar correções de curto prazo, esp. aqueles que acoplam firmemente componentes que realmente devem ser fracamente acoplados. Haverá retrabalho, faça-o CEDO para torná-lo muito mais fácil, para evitar hacks e patches que se acumularão com o tempo e se tornarão incontroláveis.
fonte
Você escreve:
Uma versão com check-in pode ser um "protótipo", na medida em que faltam recursos ou alguns recursos não são detalhados, mas todo o código verificado deve ser um código de qualidade de produção que não precise ser limpo necessariamente.
Eu acho que você está adiando sua "limpeza" para muito.
Minha regra de ouro é:
Nesse ponto, o código confirmado ainda pode conter algumas soluções alternativas ou "dívida técnica" que seria bom limpar, e talvez eu o limpe quando for o mais natural a fazer para um sub-recurso a seguir, mas ficará bem se esse código for liberado como está.
fonte