Quando é aceitável NÃO consertar janelas quebradas?

21

Em referência a janelas quebradas , há momentos em que é melhor deixar a refatoração para uma atividade futura?

Por exemplo, se um projeto para adicionar alguns novos recursos a um sistema interno existente for atribuído a uma equipe que não trabalhou com o sistema até agora e recebe um breve cronograma no qual trabalhar - pode ser sempre justificável adiar grandes refatorações para o código existente, a fim de cumprir o prazo nesse cenário?

Bullines
fonte
6
Às vezes, o chefe decide que janelas quebradas não serão consertadas, porque ele sabe que ganhará muito mais dinheiro consertando a casa inteira mais tarde.
Mouviciel
1
regra de base: a dívida técnica é ok para chegar a um prazo, mas deve, eventualmente, ser compensado e quanto mais cedo melhor
JF Dion
4
Parabéns! Você descreveu perfeitamente a "filosofia de design" do PHP.
ThomasX
1
uma curiosidade: docs.jquery.com/Won't_Fix
Jonathan dos Santos
4
O amanhã nunca chega ...
Eric King

Respostas:

25

A refatoração é - e deve ser - um processo contínuo. Não basta simplesmente atender aos requisitos com uma implementação testada e funcional que ainda está um pouco incompleta.

"Faça funcionar, depois faça funcionar melhor" .

Não me lembro onde li essa citação, mas essa é a chave para aplicar bem a refatoração, e considero pouco profissional fazer o contrário.

A refatoração contínua é como limpar os derramamentos durante o cozimento e limpar a louça após a refeição. A refatoração direcionada é como encontrar uma cozinha suja, mas ter apenas tempo para lavar um ou dois copos sujos. Você prefere viver com uma cozinha continuamente suja ou prefere manter as coisas limpas à medida que avança?

Você faz com que o código funcione e refatorá-lo para garantir que você tenha a melhor implementação possível. Se você estiver fazendo algo familiar, pode ser que você implemente o melhor código pela primeira vez, no entanto, demorará um momento para verificar novamente seu trabalho para ter certeza. Se parece que você pode melhorar seu código, tente refatorar para garantir que seu código seja no mínimo o mais enxuto e limpo possível. Isso significa que você está reduzindo o montante da dívida técnica que deixa para trás e facilita a leitura e a refatoração na próxima vez que o código precisar ser tratado. Esse é o valor principal por trás do mantra do TDD "Red-Green-Refactor", exceto que, no TDD, você refatora principalmente para remover a duplicação, vale a pena revisar também outros itens que podem ser refatorados, como classes grandes, métodos longos,

Se você se deparar com uma grande reformulação, talvez seja possível adiá-la por um tempo, principalmente se estiver com muito pouco tempo na sua programação. Porém, isso é fornecido desde que a funcionalidade do seu código não seja comprometida e também que a implementação continue atendendo aos requisitos. Esse tipo de situação deve ser uma ocorrência rara, e você pode ajudar a garantir que seja ainda mais raro se estiver refatorando continuamente à medida que avança. Ainda mais importante, porém, é que você não pode se arriscar a deixar suas grandes alterações por muito tempo; caso contrário, você acabará criando uma carga de trabalho ainda maior posteriormente, que pode ser muito mais dispendiosa para consertar ou pode resultar em um custo ainda mais caro. falha no projeto.

Tenho a impressão de que muitas pessoas tendem a confundir as definições de refatoração e reengenharia . Os dois termos descrevem estratégias para gerenciar situações muito diferentes. Se você deseja reprojetar, está assumindo o compromisso de fazer uma mudança drástica que alterará o comportamento de um sistema. Isso invalidará alguns testes e também exigirá novos testes. Ao refatorar, você garante que o sistema continue se comportando exatamenteda mesma forma que antes da alteração, no entanto, você também garante que seu código tenha longevidade e que será mais fácil manter com o tempo. Você não está "aprimorando" seu código, está comprometendo-se com um padrão profissional de código limpo que reduzirá o risco de falha e garantirá que seu código continue sendo um prazer trabalhar com ele e de um padrão profissional .

Voltando à analogia das janelas quebradas, se você quebrar a janela, deve repará-la imediatamente. Se você não percebeu que uma janela está quebrada, será necessário decidir o custo para você se deixar a janela quebrada. Agora, repita as duas frases anteriores, mas substitua Bug por window. Você acaba precisando de uma estratégia diferente. Se você criou um bug ao codificar, corrige-o imediatamente ou vê se as alterações exigirão um esforço de reengenharia e toma uma decisão comercial sobre quando será melhor resolver o problema. Para não refatorar para corrigir um problema, refatorar para garantir que seja mais fácil encontrar e corrigir problemas. Não me importo com o quão incrível você acha que seu código é, sistemas complexos sempre terão problemas que precisam ser tratados com o tempo. É disso que se trata a dívida técnica e por que a refatoração precisa ser um processo contínuo à medida que você implementa seu código , e não é deixada por um tempo arbitrário no futuro.

Portanto, em suma, a resposta que, em momentos raros, é aceitável adiar grandes alterações no código para estabelecer um prazo, no entanto, não deve ser considerada uma prática normal tratar a refatoração como um exercício independente do seu trabalho diário de implementação e certamente nunca usado como desculpa por equipes não familiarizadas com a base de código como uma opção para evitar garantir que sua implementação seja tão enxuta e limpa quanto possível, de acordo com as circunstâncias.

S.Robins
fonte
Como a citação.
Marjan Venema
1
Em muitos lugares "tempos raros" é a norma.
ozz
2
Se apenas o PHP "designers" reconheceu que a citação ...
ThomasX
1
Ótima citação, pense sobre isso - você quer que seu pintor de carros aplique a mesma lógica para consertar seu Toyota 1999 - e, nesse caso, você está preparado para pagar por um acabamento de pintura Roll Royce em um carro de US $ 1000?
mattnz
@mattnz Sua analogia não é verdadeira no desenvolvimento de software. Este não é um caso de "revestimento em ouro", é um adiantamento de custo relativamente baixo para garantir que você obtenha o máximo retorno do seu investimento. Roubando sua analogia da pintura, também é a diferença entre colocar uma demão de tinta no seu carro com um pincel largo ou usar uma cabine de pintura para obter um acabamento uniforme e agradável. Você recebe o que paga, então deseja pagar a taxa de um profissional e receber um emprego pela metade? Cortar os cantos pode economizar um pouco no curto prazo, mas incorrerá em uma dívida técnica maior no longo prazo.
S.Robins
11

Alguns desenvolvedores dizem que estão "consertando janelas quebradas" quando estão "reorganizando as espreguiçadeiras no Titanic". O código de refatoração que funciona, mas ofende seu olfato, é relativamente fácil. Se você acha que continua voltando a esse tipo de tarefa em vez de adicionar novos recursos aos usuários ou tornar o aplicativo mais utilizável para eles (otimização significa tornar o aplicativo mais rápido é bom aqui, otimização significa tornar o código mais legível) diferente), então talvez você esteja arrumando demais. Não porque arrumar é ruim, mas porque a empresa está pagando pelo desenvolvimento para desenvolver algo. Eles não querem uma solução frágil, difícil de ler e mal arquitetada, com certeza, mas também não querem uma meia solução polida e bonita.

Organize quando você precisar fazer algo simples "seguir em frente", ou quando estiver esperando por outra equipe para lhe dizer se o seu problema é realmente culpa deles ou quando você estiver aguardando uma decisão. Haverá muitas oportunidades. Se você tiver a chance de mover o aplicativo inteiro para a frente, leve-o, a menos que esteja começando a sentir que tudo se tornou frágil. Provavelmente não. Você terá a chance de refatorar - não precisa se preocupar com isso.

Para voltar à segunda metade da sua pergunta, um sprint para adicionar recursos em uma linha do tempo curta, seria errado dizer "e não faremos nenhuma refatoração, não há tempo". Também seria errado dizer "sei que já faz 6 semanas e parece exatamente o mesmo para os usuários, mas essas janelas quebradas realmente precisam ser consertadas". Encaixe a refatoração nas lacunas que ocorrem em qualquer projeto. Não se refugie em arrumar às custas de atingir a meta do projeto.

Kate Gregory
fonte
4
Alguns desenvolvedores dizem que estão "consertando janelas quebradas" quando na verdade estão "reorganizando as espreguiçadeiras no Titanic" - na verdade, muitas vezes parece ser difícil para os desenvolvedores diferenciarem entre "dívida técnica" e "não da maneira que eu faria" já fiz isso "
RevBingo 18/04/12
9

Do ponto de vista comercial, a refatoração é um investimento especulativo - investindo tempo e esforço (dinheiro) agora, na esperança de economizar mais tempo e esforço (dinheiro) em algum momento no futuro.

Sem entrar no debate sobre quanto o esforço para refatorar economizará no futuro (isso depende de muitas variáveis ​​para que seja uma discussão significativa aqui), fica claro que é hora de refatorar quando o "valor presente líquido" do custo que sai excede o custo de fazer agora.

Isso é fácil, exceto que você não tem idéia de quanto custará o furture. Você também precisa considerar todas as idéias normais de planejamento financeiro, como retorno do investimento, gerenciamento de riscos (valor da marca, responsabilidade legal, risco segurável versus risco não segurável), custo operacional etc.

Na maioria dos casos, é melhor decidir quando refatorar para as pessoas que administram o negócio. Apesar do que muitos pôsteres deste fórum expressam, os gerentes geralmente sabem mais sobre o gerenciamento de negócios do que os programadores. Eles têm uma imagem maior em mente que inclui maximizar o retorno ao acionista. É raro que consertar coisas que não estejam quebradas contribui para isso, o código não é exceção.

Edit: Eu li um artigo interessante sobre agendas de manutenção em infraestrutura crítica. A essência é que o movimento está longe da manutenção de rotina (refator) para reparar quando necessário (consertar bugs). A principal diferença são os níveis de monitoramento - por exemplo, uma usina nuclear monitora em grandes detalhes e corrige quando "quebrada", mas muito antes da falha. O que foi encontrado é que a fixação em um esquema de manutenção não custa apenas mais, mas é menos confiável devido a interrupções causadas pelo programa de manutenção. Uma idéia semelhante é necessária para o software - refatorar os bits que estão prestes a quebrar - que você só pode saber por medição.

mattnz
fonte
4
+1 apesar dos erros de ortografia :); na maioria das vezes, o cliente não está pagando por código limpo - está pagando por um resultado. Se você tiver um código limpo e nenhum resultado, não será pago e não ficará refatorando por muito tempo.
jasonk
2
Quero apenas observar que é bastante comum que o gerente tenha uma melhor noção do negócio como um todo. Infelizmente, eles costumam ter uma sensação muito pior do que o código incorreto custará no futuro, portanto, verifique se o seu gerente tem alguns dados de custo razoáveis ​​para trabalhar, se você confiar no gerente para tomar essa decisão.
Michael Kohne
A outra maneira de analisar a refatoração não é como algo a ser decidido como tarefa-alvo, mas como um meio de garantir que você não tropeça em si mesmo ao desenvolver um sistema. Frequentemente, você encontrará códigos mal fatorados que farão com que você continue modificando os testes e tentando apagar incêndios à medida que avança. Como resultado, isso pode custar mais ao cliente antecipadamente. Manter o código limpo não deve ser visto como um ouro para ele, mas como um padrão profissional para obter resultados bem-sucedidos.
S.Robins
1
@ S.Robins Estamos falando de refatoração, e não de código mal fatorado (na minha opinião o segundo é um problema, o primeiro é um bom exemplo).
Jasonk 29/04
5

É aceitável quando o dano ao negócio, corrigindo-o, é maior do que não corrigi-lo.

As situações em que isso ocorre podem ser:

  • onde um prazo ou oportunidade de negócio pode ser perdida devido ao tempo necessário para corrigir
  • onde um trecho de código está (genuinamente) programado para ser retirado em uma escala de tempo muito curta, portanto, quase não há benefício em refatorá-lo.

E essas situações ocorrem - as situações comerciais costumam estabelecer prazos artificiais que precisam ser cumpridos quando a oportunidade de negociá-los se esgotar e requisitos que têm um componente temporal - por exemplo, uma mudança na legislação ou regras tributárias que entram em vigor. uma data específica - existe.

O truque é identificar essas situações e avaliá-las adequadamente. O código que está programado para ser aposentado geralmente permanecerá por anos. Os prazos artificiais podem precisar ser cumpridos, mas geralmente podem ser cumpridos de maneiras diferentes (por exemplo, o software pode ser apresentado, demonstrado e "lançado" em uma determinada data, sem que a versão final seja necessariamente finalizada mais tarde).

Quando apresentado a esse tipo de coisa, você precisa abordá-lo com a mente aberta, mas sempre perguntar: é o que parece? As premissas envolvidas são realistas? Existe outra maneira de atingir a meta sem enviar código abaixo do padrão? Se não houver, como melhor uso o tempo disponível?

E se não houver alternativa sempre boa, mas quando vamos resolver isso?

Porque deveria quase, quase, quase sempre ser quando , não se .

Jon Hopkins
fonte
Re: prazos artificiais; No mundo ideal, qualquer projeto decente deve ter um prazo. Ouvi dizer que as equipes de produtos estão bem em escorregar por uma semana (uma semana não é grande coisa, certo?) - sem perceber o incentivo comercial - que isso estava colocando você depois do sábado preto , em comparação com o anterior. Mal movimento.
jasonk
3

Se os gerentes decidirem que desejam acumular dívida técnica . Essa é uma decisão justa a ser tomada, se alguém, por exemplo, deseja apenas um protótipo antecipado para alguns clientes iniciais, para obter feedback antecipado.

David
fonte
4
Isso acontece com muita frequência, onde os gerentes permitem que a dívida técnica acumule para cumprir um prazo apertado, apenas em vez de pagar a dívida o mais rápido possível, eles veem o próximo prazo se aproximando e em vez de agendar um horário para o próximo trabalho e dívida anterior , a dívida é ignorada e o tempo necessário é preenchido com novos recursos adicionais para liberação. Em outras palavras, a dívida nunca é paga e, antes que você perceba o quão profundo o projeto é, é tarde demais para fazer qualquer coisa para evitar que o problema fique fora de controle. Não há problema em acumular dívidas, desde que você pague rapidamente.
S.Robins
2
Alguns gerentes (especialmente não técnicos) não têm idéia do que você está falando quando menciona dívida técnica. Alguns até acham que você está tentando convencê-los a ir embora e brincar com as coisas, em vez de fazer um trabalho real.
quickly_now
Essa é a razão por que a nossa organização não tem gerentes: Open-Org.com;)
David
1
A maioria dos gerentes não é inteligente o suficiente para entender as desvantagens da dívida técnica; portanto, você acaba com uma dívida técnica que acumula continuamente até você falir tecnicamente e ser forçado a reescrever todo o sistema.
Wayne Molina
1

Você pode pensar nisso da mesma maneira que pedir crédito. É aceitável pedir dinheiro emprestado para investir no X no curto prazo e pagar a longo prazo? Não existe uma resposta definitiva, ela pode ser do melhor interesse da organização (por exemplo, para atender às expectativas atuais do cliente) ou pode ser um desastre se for realizada de forma irresponsável.

Tudo se resume a prioridades, e a gerência deve estar ciente de que, embora a prioridade número um seja fazer com que o "código funcione", implemente novos recursos e atenda às expectativas do cliente, toda vez que você deixa janelas quebradas, torna a prioridade número um mais lenta , mais difícil e exigindo mais investimento em recursos. Além disso, 99% das vezes não é possível parar de desenvolver novos recursos e concentrar todos os esforços na "correção da base de código".

Concluindo, sim, às vezes é aceitável deixar janelas quebradas, assim como é aceitável pedir um empréstimo ... lembre-se de que você realmente precisa pagar por isso no futuro. E no futuro, o tempo para fazê-lo provavelmente não será muito maior do que o tempo que você tem agora.

jlemos
fonte
0

Normalmente, quando você puder, deve corrigi-lo. Isso evitará o possível tempo gasto em manutenção. No entanto, algumas práticas bárbaras não-ágeis tendem a deixar o status quo enquanto durar. Alguns gerentes têm medo dos "efeitos imprevistos" da mudança.

Minha opinião é deixá-lo apenas se estiver funcionando como deveria (apenas quebrado pela otimização, mas não pela funcionalidade) e você não terá tempo para testá-lo, se fizer alguma refatoração. No entanto, observe que ele deve ser corrigido mais tarde, o mais rápido possível.

Se estiver quebrado pela funcionalidade e os novos recursos dependerem dele, seria melhor corrigi-lo o mais rápido possível.

Dorward Villaruz
fonte
0

A maioria dos programadores está no negócio de ganhar dinheiro para seu empregador. Então, quando a refatoração deve acontecer: quando você ganha dinheiro com firmeza. Refatoração é o tempo gasto não gasto em outros projetos e o tempo economizado no futuro nesse projeto.

Se vale a pena, depende principalmente do seu gerente.

Pieter B
fonte
1
-1; Esse tipo de atitude é o que faz com que os sistemas de software apodreçam porque a refatoração é vista como "tempo que poderia ser gasto em coisas novas".
Wayne Molina
1
Refatorar é tempo não gasto em coisas novas.
Pieter B
@Wayne M: As coisas são engenheiros de software geralmente não decidem o que as coisas são feitas, os negócios e os gerentes fazem. Claro, todo mundo gostaria de refatorar sempre que quisesse, mas isso realmente não é a realidade ... pelo menos nos meus 7 anos de experiência na profissão.
11114 James
+1 Esse tipo de atitude é o que agrega valor a quem paga seu salário. Sem ele, todo o seu trabalho poderia ser terceirizado.
MarkJ
0

Os programadores devem informar ao lado da empresa a extensão da dívida técnica, para que possam tomar uma decisão informada. Se a necessidade de chegar ao mercado mais cedo supera o risco do seu código, você não tem muita escolha. A falta de fluxo de caixa superará muitas decisões técnicas.

Para colocar alguns dos problemas em uma perspectiva não técnica, aponte o tempo estendido para corrigir bugs e adicionar novos recursos. Se a gerência possui um plano de vendas e marketing, eles podem entender isso. Eles odeiam ter que dizer aos clientes que essas coisas levarão mais tempo.

Se você está pensando em expandir sua equipe, talvez seja um bom momento para contratar um desenvolvedor júnior. A cobertura do teste será um grande salvador neste caso. Eles aprenderão mais fazendo do que lendo a documentação.

JeffO
fonte
0

pode ser justificável adiar grandes refatorações para o código existente, a fim de cumprir o prazo nesse cenário?

  • Se algo está quebrado, provavelmente não. Você não vai dirigir um carro com freios parcialmente trabalhando, não é? (A menos que o risco de não chegar a algum lugar a tempo seja maior do que o risco de travar por causa dos freios com defeito.) Longe da solução ideal, mas infelizmente isso acontece.

No entanto, se você estiver falando sobre refazer o código de trabalho, considere o seguinte:

  • Se dependesse de nossos desenvolvedores seniores ou diretor técnico, nunca lançaríamos nenhum software. Nós sempre re-fatoramos e lutamos pelo perfeccionismo.

  • Se a re-fatoração tiver um impacto negativo na lucratividade dos negócios, ela deverá ser remarcada.

  • Se sua empresa prometeu entregar determinadas funcionalidades em uma determinada data, você deveria refatorar mais tarde. Pense na caridade do Red Nose Day - todos os anos, eles podem coletar doações por um período de 24 ou 48 horas. Não há como eles redefinirem sua base de código se acham que isso pode impedi-los de receber doações nesse intervalo de tempo. Além disso, se houver uma janela quebrada, mas isso não afetará a capacidade de receber doações, é bem provável que eles optem por não fatorar novamente.

  • Você sempre encontrará uma maneira melhor de fazer alguma coisa. É um processo natural e é muito importante poder traçar uma linha.

CodeART
fonte
Seria bom receber algum feedback sobre votos negativos: D
CodeART 1/12/12
2
Concordo, com tantos votos negativos, parece que alguém acabou de ter um dia ruim e se deparou com vários votos negativos.
Sam Goldberg
-1

Em resposta à sua pergunta sobre refatoração, eu diria "sim". Como alguém apontou nas respostas acima, a refatoração é um processo em andamento e, algumas vezes, há decisões táticas e de negócios que substituem a necessidade de reescrever o código que já está funcionando (embora talvez de uma maneira klugey).

Sobre "janelas quebradas": ouvi esse termo pela primeira vez no contexto de desenvolvimento de software, há cerca de 10 anos. Mas naquela época, era usado para descrever a permissão de testes de unidade quebrados . Isso descrevia o cenário em que as pessoas têm a tentação de não consertar testes de unidade quebrados, porque parece mais conveniente apenas lembrar quais testes são "aceitáveis ​​para falhar", em vez de consertar os testes quebrados (que foram validamente quebrados devido a interface ou requisitos alterações, por exemplo).

Penso que aplicar a metáfora da janela quebrada a testes de unidade quebrados é mais adequado e mais descritivo do perigo de permitir "janelas quebradas" na vizinhança do software. Na minha opinião, se você estivesse falando de testes de unidade quebrados (como janelas quebradas), a resposta seria que nunca está tudo bem. (Na medida em que podemos dizer nunca ...)

Sam Goldberg
fonte
Qual é o motivo da votação negativa? Algo dito aqui não está correto? Ou apenas editores vingativos?
Sam Goldberg
-1

Se estiver realmente quebrado, deve ser corrigido.

Mas está realmente quebrado? Tem certeza de que não está apenas equiparando "não bonito" a quebrado?

Você precisa aplicar um cálculo de "valor irrecuperável" antes de redefinir o código de trabalho porque não gosta do estilo ou porque acha que isso causará problemas no futuro.

Para refazer o código que você escreveu na semana passada, o custo irrecuperável é o tempo que você gastou para codificá-lo na semana passada, não vale a pena se preocupar em saber se o código é substancialmente aprimorado.

Re-fatoração de código que passou por teste de unidade. Agora você não precisa apenas reescrever, é necessário redefinir e reexecutar todos os testes realizados até agora, isso está começando a parecer caro.

Re-fatoração de código que foi para produção. Ainda mais testes a serem feitos, além de uma implementação para os usuários e o risco de entregar algo que não funciona tão bem quanto a versão antiga. Você precisa justificar isso e limpá-lo com o grande chefe antes de prosseguir.

Re-fatorar código que entrou em produção por um tempo e passou por várias versões e correções de bugs. A menos que você saiba que o software vai parar de funcionar, nem vá lá!

James Anderson
fonte
Geralmente "não bonito" anda de mãos dadas com "quebrado". O código que não está escrito corretamente é mais difícil de manter e incluir novos recursos; portanto, você precisará reescrever esse código, pois negligenciou a refatoração ao longo do caminho.
Wayne Molina
2
O código que é testado e em produção sem relatórios de erros pendentes está funcionando. Muito tempo e dinheiro foram investidos para entrar nesse estado. Código bonito é exatamente isso - código bonito.
James Anderson
Discordo. O código pode funcionar, mas pode ser um aborrecimento para manter e adicionar recursos; código como este está quebrado porque é rígido e "fedido". Código escrito corretamente é geralmente bonito E testado E, o mais importante, é fácil de manter e aprimorar.
Wayne Molina
@Wayne M: Uau, Wayne, você realmente não tem ideia. Se você chegar à PM, seus desenvolvedores o amarão, mas sua carreira provavelmente não será longa. Você tem que desenhar a linha em algum momento. Suponho que é você quem está votando contra todos que não concordam com seus sonhos?
James
1
@WayneM - então você criaria um "defeito" porque não gosta da aparência do código. O código é escrito para fazer um trabalho - se ele faz o trabalho, então está funcionando. Os custos de manutenção podem ser altos, mas precisam ser mais baratos que uma reescrita.
James Anderson
-2

Foi minha experiência que o prazo final é a coisa mais importante para os negócios. Realmente depende de quem usará seu aplicativo. No meu caso, era para o software do sistema operacional para celulares ... prazos perdidos significavam metas de vendas perdidas e acertos nos preços das ações.

Nos deparamos com muitos momentos do WTF quando analisamos o código que herdamos e claramente precisávamos ser alterados. No entanto, como esse código funcionou 'quase' (a assincronicidade é pouco compreendida), não havia incentivo para a gerência permitir a refatoração enquanto havia compromissos pendentes a serem cumpridos. Não foi até que um inseto fosse visto "em estado selvagem" que poderíamos mudar qualquer coisa, mesmo que pudéssemos quebrá-lo facilmente através de casos obscuros. Uma vez refatorei aproximadamente 10 mil linhas de código no meu tempo e acabei tendo que jogá-lo fora. O tempo necessário para testes e outras revisões etc. não poderia ser justificado.

James
fonte
Estou feliz que a realidade do desenvolvimento de software pareça ter sido perdida para algumas pessoas #
James