Como refatorar uma base de código enquanto outras pessoas rapidamente se comprometem com ela?


18

Estou em um projeto privado que eventualmente se tornará código aberto. Temos alguns membros da equipe, talentosos o suficiente com as tecnologias para criar aplicativos, mas não desenvolvedores dedicados que podem escrever código limpo / bonito e, o mais importante, de manutenção a longo prazo.

Decidi refatorar a base de código, mas é um pouco complicado, pois alguém da equipe de outro país com o qual não estou em contato regular pode estar atualizando essa coisa totalmente separada.

Sei que uma solução é se comunicar rapidamente ou adotar melhores práticas de gerenciamento de projetos, mas ainda não somos tão grandes assim. Eu só quero limpar o código e mesclar bem o que ele atualizou. Usar um ramo seria um plano adequado? Uma fusão de melhores esforços? Algo mais?

Respostas:


35

Uma coisa que as pessoas geralmente deixam de considerar é que uma arquitetura limpa não apenas acelera a manutenção a longo prazo, mas também acelera o desenvolvimento no momento . Não tente isolar as alterações de seus colegas até que elas estejam "concluídas". Suas alterações os ajudarão a serem mais produtivos e menos propensos a erros.

O erro mais frequente que as pessoas cometem ao realizar um refator grande é não se fundir com frequência suficiente, ao invés disso, tentando fazê-lo em um "big bang". A maneira certa de fazer isso é fazer o menor refator possível, testá-lo e fundi-lo ao ramo do seu colega, e ensiná-lo sobre a mudança para que ele possa incorporá-la daqui para frente. Idealmente, você está fazendo uma mesclagem por dia ou uma por semana, no mínimo.


17
Sim Sim Sim. Resista à tentação de fazer um tour-de-force solo de um mês apenas para descobrir que a base de código que você deve refatorar mudou completamente e você precisa começar tudo de novo. Melhor fazê-lo um passo de cada vez.
tdammers

Exatamente certo! Refatorações grandes ir a lugar nenhum (consulte Netscape 6 , ou a pirâmide Projeto )
Andomar

8

Você nunca "não é grande o suficiente para se comunicar". Se seus dedos puderem digitar, seus lábios também poderão falar. No final do dia, a melhoria da tecnologia é de 85% na comunicação e 15% na técnica. Só porque você prefere ficar sentado codificando do que ter conversas difíceis com alguém ... não significa que é uma boa ideia. A comunicação é realmente a parte mais difícil do que você está tentando, mas não a evite.


Não é realmente a dificuldade de se comunicar, é que eu não quero que o atual desenvolvedor desacelere. Na verdade, nem tenho certeza se ele precisa aprender da maneira certa, desde que possa ser refatorado. Ele não é um programador primeiro, ele é um cientista em outro campo.
Incognito

+1. Você não pode compartilhar uma base de código com alguém sem comunicar
MarkJ

4

Sim, um ramo é uma boa solução para isso.

Eu sugiro que você comece a trabalhar nisso em uma ramificação e certifique-se de que ele se aplique de forma limpa em relação à sua corrente HEADnesse meio tempo (por exemplo, faça rebotes de teste e mescla em intervalos regulares para garantir que você possa aplicar suas alterações facilmente e seus testes ainda passarem - - também procuregit rerere ajuda gitcom isso). Depois que você terminar, rebase e mescle suas alterações no seu HEAD.

Quanto mais cedo você começar a trabalhar nisso, melhor, pois a alteração da arquitetura se torna cada vez mais trabalhos, mais frio o código fica. Além disso, pode haver muitas instâncias de código codificado manualmente espalhadas por toda a base de código, onde, por exemplo, sua função auxiliar nova e mais brilhante pode ter tornado as coisas muito mais simples.


1
-1: Não. Veja a resposta de @Karl Bielefeldt.
Jim G.

Sim? Não discordo de Karl, por isso fiz questão de começar rápido.
Benjamin Bannier

E eu estou dizendo: "Não ramifique e depois junte novamente". Na melhor das hipóteses, é um esforço desperdiçado. Na pior das hipóteses, você fará uma bagunça enorme.
Jim G.

3

Você já considerou a opção "Não faça isso ainda"?

Embora fazer esse trabalho em uma ramificação separada seja provavelmente a melhor abordagem, você está se preparando para uma fusão maciça e dolorosa no final da linha.

Os outros caras provavelmente estão adicionando muitas novas funcionalidades, alterando a funcionalidade existente e possivelmente removendo alguma funcionalidade.

Depois que o desenvolvimento mainstream tiver diminuído um pouco em algum momento no futuro, você poderá estar em uma posição muito mais fácil de refatorar.


+1. Se sua base de código estiver em fluxo maciço, provavelmente não é o melhor momento para tentar uma grande reescrita. Escolha um momento no seu ciclo de desenvolvimento em que as coisas estão mais calmas.
anon

2

tl; dr - Parece que é hora de avançar para as grandes ligas. Colocar batom em um porco não a torna mais bonita, a menos que você goste desse tipo de coisa ...

O problema das pessoas

O primeiro problema é a sincronização de confirmação. Se você tiver várias pessoas trabalhando no mesmo código ao mesmo tempo, precisará de apenas uma regra para evitar problemas:

Rule 1: Always pull before you merge/rebase

No que diz respeito ao DVCS, é difícil fazer alterações em uma filial remota (ou seja, o repositório principal) e muito fácil fazer alterações no local. Cada pessoa é responsável por ajustar suas próprias adições de código ao todo maior, sem problemas. A menos que duas pessoas se comprometam exatamente ao mesmo tempo, você não deve experimentar. O acesso confirmado ao mestre de origem / remoto deve ser limitado a apenas alguns desenvolvedores e eles devem receber alterações dos outros desenvolvedores por meio de ramificações de rastreamento remoto.

O problema do código

Como você sabe que as alterações feitas não quebram o código?

Resposta simples ... Faça testes para provar que não. Se você ignorar a escola de pensamento TDD (Design Orientado a Testes), o objetivo principal dos testes é adicionar um nível de verificação que permita alterar o código sem quebrá-lo.

Rule 2: Don't make assumptions, write proofs (ie tests).

Além disso, toda a gama de testes deve ser executada antes de você enviar para o mestre de origem / remoto.

Mantenha seus commits tão pequenos e concisos quanto possível. Dessa forma, se você precisar fazer o backup de uma alteração que quebrou algo mais tarde, você evitará a necessidade de reimplementar as partes que não quebraram o código.

Você pode precisar de alguma reestruturação organizacional primeiro

Se as soluções acima não puderem ser facilmente aplicadas, provavelmente há alguns problemas com a estrutura de desenvolvimento que precisam ser resolvidos primeiro.

O proprietário do projeto deve ser o gatekeeper. Se houver problemas de sincronização de confirmação, provavelmente haverá muitas pessoas com acesso de confirmação. Mesmo em projetos maciços como o kernel do Linux, apenas alguns desenvolvedores têm acesso confirmado ao repositório principal de origem / remoto. Na verdade, existem vários níveis de repositórios para gerenciar confirmações. Em vez de um modelo de consolidação de camada única, onde todos estão enviando suas alterações para a origem, o modelo hierárquico possui gatekeepers que realizam alterações e verificam sua qualidade antes da inclusão no projeto. O modelo hierárquico de confirmação pode ser dimensionado muito maior e mais eficaz que o modelo de camada única sem sacrificar a qualidade.

Para os devs que não se cometem acesso, eles devem aprender a criar o seu próprio remotas ramificações de controle (git e Gitorious são bons para isso) para que os devs que fazer se o acesso de submissão pode facilmente puxar / integrar filiais na origem. Se as alterações forem pequenas, os patches também funcionarão.

A capacidade de obter alterações antes de fazer uma mesclagem / rebase pressupõe que você não esteja desenvolvendo em sua ramificação principal local. A maneira mais fácil de lidar com isso é fazer um puxão inicial antes de começar a codificar e, em seguida, fazer todo o seu trabalho nesse ramo. A maneira mais difícil é ramificá-lo antes de mesclar e reverter o mestre.

Defina o estilo de codificação do projeto em geral e faça com que os desenvolvedores o sigam. Os desenvolvedores contribuintes devem escrever um código que esteja em conformidade com os padrões / normas do projeto para minimizar a limpeza. O estilo de codificação pode ser uma grande barreira do ego em um projeto aberto. Se nenhum padrão for definido, todo mundo codificará em seu próprio estilo preferido e a base de código ficará muito feia muito rapidamente.

O mito do "Mês do Homem Mítico"

Acredite ou não, os projetos de código aberto maiores / mais bem-sucedidos não são executados como uma democracia. Eles são executados como uma hierarquia. Afirmar que um projeto não pode crescer efetivamente além de 8 a 10 desenvolvedores é ingênuo. Se isso fosse verdade, megaprojetos como o Linux Kernel não existiriam. A questão mais profunda é que dar a todos acesso de confirmação apenas dificulta a comunicação eficaz.

O problema do mítico homem mês pode realmente ser superado. Você só precisa executar seu projeto como os militares. Existem muitos níveis na hierarquia, porque é do conhecimento geral que pessoas individuais são realmente efetivas apenas no gerenciamento de comunicações com um punhado de pessoas. Desde que nenhum indivíduo seja responsável por gerenciar o trabalho de mais de 5 a 7 pessoas, o sistema poderá ser escalado indefinidamente.

Pode limitar os desenvolvedores melhores / experientes a fazer mais integração e design / planejamento de nível superior, mas isso não é uma coisa ruim. Parte da ampliação é tomar a decisão de decidir que o projeto precisa de um plano de longo prazo. As pessoas dos níveis mais altos que têm o maior investimento (o tempo também é um recurso) no futuro dos projetos devem ser encarregadas de tomar as grandes decisões.

É bom ouvir sobre um projeto de código aberto passando por dores de crescimento. Parabéns e boa sorte.


-1

código limpo / bonito e, mais importante, de manutenção a longo prazo.

Na minha experiência, limpo / bonito é o inimigo da manutenção. Código bonito frequentemente:

  • Possui uma camada na estrutura que introduz um nível mais alto de abstração
  • Otimiza a reutilização de código, resultando em muitas dependências
  • Tenta resolver o problema genérico em vez do específico

Por outro lado, código sustentável:

  • Está escrito diretamente na estrutura, para que todos os desenvolvedores possam lê-la
  • Otimiza para um baixo número de dependências, para que uma mudança em uma área não afete outra
  • Não tenta resolver mais problemas do que precisa

Sua bela descrição de código também pode acompanhar o código de manutenção, porque quando você introduz um nível mais alto de abstração e otimiza o código para reutilização, é assim que é mais fácil manter a manutenção.
Karthik Sreenivasan

Exceto que a abstração não resistirá ao teste do tempo. E qualquer problema com a abstração eleva uma correção local para uma correção que potencialmente tem impacto no aplicativo.
Andomar 21/03
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.