Existem casos excepcionais em que podemos aceitar código duplicado?

57

Estou trabalhando em um projeto de software em que precisamos construir três APIs. Um para o canal bancário home , um para o canal agência e um terceiro para o canal mobile .

A API da agência é a mais completa, pois tem todas as funcionalidades. Depois, API Home menor e API móvel.

Os arquitetos aqui fizeram uma camada comum (serviços EJB entre canais compartilhados por todas as APIs). Mas as APIs são diferentes.

Não há grande diferença por enquanto entre as APIs. A grande equipe começou com o canal da agência e estamos adaptando agora para o canal doméstico. Estamos apenas enriquecendo objetos especificamente para nosso aplicativo doméstico. Caso contrário, o código é 95% semelhante entre APIs. As APIs são criadas em cima do Spring MVC e possuem (controladores, modelos e alguns utilitários).

Basicamente, os controladores estão fazendo o mapeamento BO para ChannelObject (não me parece o lugar certo para fazer isso), e alguns utilitários e serializadores adicionais. Tudo está duplicado por enquanto. Eles estão dizendo que o motivo da duplicação é que eles querem as APIs independentes. "Se amanhã quisermos um comportamento diferente para casa do que para a agência ou para o celular, não vamos nos debater!"

Existe um caso em que devemos aceitar códigos duplicados?

    
por Mohamed Amine Mrad 10.08.2017 / 15:37
fonte

4 respostas

71

A duplicação pode ser a coisa certa a fazer, mas não por este motivo.

Dizer "podemos querer que esses três lugares na base de código se comportem de maneira diferente, embora agora sejam idênticos" não é uma boa razão para a duplicação em larga escala. Esta noção poderia ser aplicada a todos os sistemas , e poderia ser usada para justificar qualquer duplicação, o que obviamente não é razoável.

A duplicação deve ser tolerada apenas quando a remoção for globalmente mais cara agora por algum outro motivo (não pode pensar em uma boa agora, mas tenha certeza de que pode haver uma - praticamente tudo na programação é um trade-off e não uma lei).

Para o que você está fazendo, a solução correta poderia ser, por exemplo, extrair o comportamento que é duplicado agora em uma Estratégia ou algum outro padrão que modela o comportamento como classes e, em seguida, usa três instâncias da mesma classe. Dessa forma, quando você faz deseja alterar o comportamento em um dos três locais, você só precisa criar uma nova Estratégia e instanciar isso em um só lugar. Dessa forma, você só precisa adicionar algumas classes e deixar o resto da base de código quase intocado.

    
por 10.08.2017 / 16:13
fonte
87

Sandi Metz, renomada engenheira de software e autora do ecossistema Ruby, tem uma ótima postagem no blog e uma conversa , onde ela também fala sobre a relação entre a duplicação e abstração. Ela chega à seguinte conclusão

duplication is far cheaper than the wrong abstraction

E eu concordo completamente com ela. Deixe-me dar mais contexto a esta citação. Às vezes, encontrar a abstração correta é muito difícil. Em tais casos, é tentador simplesmente ir para qualquer abstração para reduzir a duplicação. Mas depois você pode descobrir que sua abstração não é válida para todos os casos. No entanto, é caro mudar tudo de novo e seguir um caminho diferente (para uma explicação muito melhor, veja-a falar!).

Então, sim, para mim, há casos excepcionais, em que aceitar a duplicação é a decisão certa, especialmente quando você não tem certeza do que está por vir e é provável que os requisitos mudem. De sua postagem, considero que há muita duplicação agora, mas seus colegas sugerem que isso pode mudar e não combinar os dois aplicativos uns com os outros. Na minha opinião, este é um argumento válido e não pode ser desconsiderado em geral.

    
por 10.08.2017 / 16:17
fonte
34

Se as pessoas começarem a raciocinar sobre design com as palavras "se amanhã" , isso geralmente é um grande sinal de alerta para mim, especialmente quando o argumento é usado para justificar uma decisão que inclui trabalho e esforço extras , para quem ninguém realmente sabe se isso vai dar retorno, e qual é mais difícil de mudar ou reverter do que a decisão oposta.

A duplicação de código reduz o esforço apenas por um curto período, mas aumentará os esforços de manutenção quase imediatamente, proporcionalmente ao número de linhas duplicadas de código. Note também que uma vez que o código é duplicado, será difícil remover a duplicação quando se verificar que esta foi a decisão errada, enquanto que se não duplicar o código agora, ainda é fácil introduzir a duplicação mais tarde se ficar preso ao DRY foi a decisão errada.

Disse que, em organizações maiores, às vezes é benéfico favorecer a independência de equipes diferentes sobre o princípio DRY. Se remover a duplicação extraindo as partes comuns de 95% das APIs, dois um novo componente leva a um acoplamento de duas equipes independentes, isso pode não ser a decisão mais sábia. Por outro lado, se você tiver recursos limitados e houver apenas uma equipe mantendo as duas APIs, tenho certeza de que será do seu próprio interesse não criar nenhum esforço duplo e evitar duplicações de código desnecessárias.

Note ainda que faz diferença se as APIs "Home" e "Agency" forem usadas exclusivamente por aplicativos totalmente diferentes, ou se alguém pode tentar escrever uma compilação de componente sobre as APIs que podem ser usadas em um "Home" contexto, bem como num contexto de "Agência". Para esta situação, ter as partes comuns das APIs exatamente idênticas (que você só pode garantir se as partes comuns não forem duplicadas), facilitará muito o desenvolvimento de tal componente.

Então, se houver diferentes subequipes, cada um responsável por cada uma das APIs, cada uma com um cronograma e recursos diferentes, então é hora de duplicar o código, mas não "apenas no caso" .

    
por 10.08.2017 / 16:23
fonte
13

Duplicação para impedir o acoplamento . Digamos que você tenha dois grandes sistemas e os force a usar a mesma biblioteca. Você pode estar acoplando o ciclo de lançamento de ambos os sistemas. Isso pode não ser tão ruim, mas vamos dizer que um sistema precisa introduzir uma mudança. O outro precisa analisar a mudança e pode ser afetado. Às vezes pode quebrar as coisas. Mesmo que ambas as partes possam coordenar as mudanças, pode haver muitas reuniões, passando por gerentes, testes, dependências e o fim da pequena equipe autônoma.

Então você está pagando o preço do código duplicado para ganhar autonomia e independência.

    
por 11.08.2017 / 10:17
fonte

Tags