Tenho certeza de que há um nome para esse anti-padrão em algum lugar; no entanto, não estou familiarizado o suficiente com a literatura antipadrão para conhecê-lo.
Considere o seguinte cenário:
or0
é uma função de membro em uma classe. Para o melhor ou para o pior, depende muito das variáveis dos membros da classe. O Programador A aparece e precisa de funcionalidades como, em or0
vez de chamar or0
, o Programador A copia e renomeia a classe inteira. Suponho que ela não ligue or0
porque, como eu digo, depende muito das variáveis de membro para sua funcionalidade. Ou talvez ela seja uma programadora júnior e não saiba como chamá-la de outro código. Então agora temos or0
e c0
(c para cópia). Não posso culpar completamente o programador A por essa abordagem - todos temos prazos apertados e hackeamos o código para concluir o trabalho.
Vários programadores mantêm or0
a versão agora orN
. c0
agora é a versão cN
. Infelizmente, a maioria dos programadores que mantinham a classe contendo or0
parecia desconhecer completamente - qual c0
é um dos argumentos mais fortes que posso pensar pela sabedoria do princípio DRY. E também pode ter havido manutenção independente do código em c
. De qualquer forma, parece que or0
e c0
foram mantidas independentes um do outro. E, alegria e felicidade, um erro está ocorrendo no cN
que não ocorre orN
.
Então, eu tenho algumas perguntas:
1.) Existe um nome para esse anti-padrão? Eu já vi isso acontecer com tanta frequência que acho difícil acreditar que esse não seja um anti-padrão nomeado.
2.) Eu posso ver algumas alternativas:
a.) Corrija orN
para obter um parâmetro que especifique os valores de todas as variáveis de membro necessárias. Em seguida, modifique cN
para chamar orN
com todos os parâmetros necessários passados.
b.) Tente portar manualmente as correções de orN
para cN
. (Lembre-se de que não quero fazer isso, mas é uma possibilidade realista.)
c.) Recopie orN
para - cN
novamente, eca, mas eu listo por uma questão de completude.
d.) Tente descobrir onde cN
está quebrado e, em seguida, repare-o independentemente orN
.
A alternativa a parece ser a melhor correção a longo prazo, mas duvido que o cliente me permita implementá-la. Nunca tempo ou dinheiro para consertar as coisas direito, mas sempre tempo e dinheiro para consertar o mesmo problema 40 ou 50 vezes, certo?
Alguém pode sugerir outras abordagens que eu talvez não tenha considerado?
fonte
Respostas:
é apenas chamado de código duplicado - não conheço mais nomes sofisticados para isso. As consequências a longo prazo são as que você descreveu e são piores.
Obviamente, eliminar a duplicação é a opção ideal, se possível. Pode levar muito tempo (em um caso recente em nosso projeto legado, eu tive vários métodos duplicados em mais de 20 subclasses em uma hierarquia de classes, muitos dos quais evoluíram evolutivamente suas pequenas diferenças / extensões ao longo dos anos. cerca de 1,5 anos através de sucessivas redações e refatoração de testes unitários para eliminar todas as duplicações.
Nesse caso, você ainda pode precisar de uma ou mais das outras opções como correções temporárias, mesmo se decidir começar a eliminar a duplicação. No entanto, qual deles é melhor depende de muitos fatores e, sem mais contexto, estamos apenas tentando adivinhar.
Muitas pequenas melhorias podem fazer uma grande diferença a longo prazo. Você também não precisa necessariamente da aprovação explícita do cliente - uma pequena refatoração toda vez que você toca na classe para corrigir um bug ou implementar um recurso pode percorrer um longo caminho ao longo do tempo. Apenas inclua algum tempo extra para refatoração nas estimativas de tarefas. É como a manutenção padrão para manter o software saudável a longo prazo.
fonte
Há uma referência ao padrão WET (We Enjoy Typing), mas não sei se é um nome padrão.
fonte
Se eu entendi direito, há muita coisa acontecendo na classe. Isso cria métodos que não seguem o princípio da responsabilidade única . Levando ao código que precisa ser movido, pedaços retirados enquanto outros são deixados de fora. Isso também pode criar muitos membros.
Você também deve revisar os modificadores de acessibilidade. Garanta que as coisas públicas sejam de fato públicas. O consumidor não precisa saber sobre cada pequeno membro ... use o encapsulamento.
Isso exige um refator. Parece também que o código está sendo escrito sem design inicial. Veja o desenvolvimento orientado a testes. Escreva o código como deve ser chamado, em vez de chamar o código, no entanto, ele é implementado. Veja no TDD algumas dicas de como realizar a tarefa.
fonte
Se você estiver copiando código, apresentará uma dívida técnica de manutenção dupla ou mais especificamente: duplicação de código .
Geralmente isso é corrigido através da refatoração. Mais especificamente, você redireciona todas as chamadas para uma nova função (ou um novo método em uma nova classe) que possui o código comum. A maneira mais fácil de começar é remover todo o código copiado e ver quais quebras, nas quais você corrige, redirecionando as chamadas para o código comum.
Conseguir que seu cliente concorde em refatorar o código pode ser difícil, pois é difícil convencer uma pessoa não técnica a consertar uma dívida técnica. Portanto, na próxima vez que você fornecer estimativas de tempo, inclua apenas o tempo necessário para refatorar suas estimativas . Na maioria das vezes, os clientes assumem que você está limpando o código durante o tempo em que faz a correção.
fonte
Parece código de espaguete para mim. A melhor solução é refatorar / reescrever.
fonte
Você diz que não pode culpar completamente A - mas copiar uma classe dessa maneira é realmente imperdoável. É uma falha enorme no seu processo de revisão de código. É possivelmente a falha mais maciça, sem nenhuma revisão de código.
Se você pensa que precisa produzir um código terrível para cumprir um prazo, a solicitação de prioridade mais alta absoluta para a liberação depois disso deve ser a de corrigir o código terrível AGORA. Então seu problema se foi.
O princípio DRY é para situações que não são perfeitas e podem ser melhoradas. Duplicar uma classe é um calibre totalmente novo. Eu o chamaria primeiro de "código duplicado" e, com o tempo, ele mudará para o pior de todos os desperdiçadores de tempo, "código duplicado divergente": várias cópias do mesmo código que são quase, mas não totalmente idênticas, e ninguém sabe se as diferenças são intencionais, coincidência ou bugs.
fonte
Quase uma década atrasada para essa parte, mas o nome desse antipadrão é Mudança divergente , onde várias classes incluem cópias do mesmo comportamento, mas à medida que o tempo e a manutenção progridem e algumas classes são esquecidas, esses comportamentos divergem.
Dependendo de qual é o comportamento compartilhado e como ele é compartilhado, ele pode ser chamado de Cirurgia com Espingarda , a diferença é que aqui um único recurso lógico é fornecido por muitas classes, e não por uma única.
fonte