Como você mergulha em grandes bases de código?

145

Quais ferramentas e técnicas você usa para explorar e aprender uma base de código desconhecida?

Estou pensando em ferramentas como grep, ctagstestes de unidade, teste funcional, geradores de diagrama de classes, gráficos de chamada, métricas de código sloccounte assim por diante. Eu estaria interessado em suas experiências, nos ajudantes que você usou ou escreveu e no tamanho da base de código com a qual você trabalhou.

Percebo que familiarizar-me com uma base de código é um processo que ocorre com o tempo, e familiaridade pode significar qualquer coisa, de "Sou capaz de resumir o código" a "Posso refatorar e encolher para 30% do tamanho". Mas como começar?

miku
fonte
3
Eu gostaria de ver como isso também é respondido; geralmente acabo reescrevendo tudo se o código for muito complexo (ou mal escrito), e isso provavelmente é inaceitável / imprudente para grandes projetos.
21412 Jeffrey Sweeney

Respostas:

55

o que eu sempre fiz é o seguinte:

Abra várias cópias do meu editor (Visual Studio / Eclipse / Whatever) e, em seguida, depure e faça quebras de linha percorrem o código. Descubra o fluxo do código, empilhe o rastreio para ver onde estão os pontos principais e vá a partir daí.

Posso olhar método após método - mas é bom clicar em algo e depois ver onde no código ele é executado e seguir adiante. Vamos ver como o desenvolvedor queria que as coisas funcionassem.

PSU_Kardi
fonte
3
Sim, defina um ponto de interrupção em um botão que inicie uma parte importante da lógica e avance. É o que eu sempre faço.
Joeri Sebrechts
11
+1 Sim, é o que eu faço também, mas não conheço nenhuma maneira de facilitar o trabalho. De acordo com minha experiência, pode levar semanas até eu me sentir seguro, fazendo alterações, e meses antes de estar "em casa" no código. Certamente ajuda se você puder fazer perguntas aos desenvolvedores.
Mike Dunlavey
11
além disso: geralmente começo por um recurso. Digamos que eu queira saber como isso envia e-mails? então procuro "sendEmail", ponto de interrupção lá e, em seguida, faço como descrito. Então você descobrir algum componente mágico que faz algo, e ir para isso, e ver como isso funciona
Lacrymology
11
+1, mas às vezes antes de configurar os pontos de interrupção, adiciono a função de impressão na primeira linha de quase todas as funções para ver a hierarquia de chamadas das funções.
MRZ
@mrz É uma ideia interessante adicionar a função de impressão. Eu acho que uma ferramenta pode ser feita para automatizar isso. E pode não ser necessariamente uma função de impressão, mas uma função de registro personalizada. Portanto, sempre que experimentamos um novo recurso com algum código desconhecido, podemos encontrar facilmente o método que chama a cadeia desse recurso no log gerado pela ferramenta.
smwikipedia
64

Como você come um elefante?

Uma mordida de cada vez :)

Sério, eu tento conversar com os autores do código primeiro.

user2567
fonte
116
Como você codifica um elefante? Um byte de cada vez!
Mason Wheeler
7
o poder da comunicação é muitas vezes subestimada
Poseid
17
+1 Por perguntar a um humano. E não tenha medo de parecer estúpido. Diga a eles todas as suposições que você fez sobre o código e todas as conclusões a que chegou sobre como ele funciona e o que faz. Eles informarão que você está incorreto. Essa pequena lesão no seu ego poupará tantas horas a longo prazo que seus colegas poderão considerá-lo uma quase divindade.
PeterAllenWebb
Obviamente, isso pressupõe que o autor do código esteja disponível.
Erick Robertson
11
@ErickRobertson ... e ele não é um idiota.
smwikipedia
39

Preciso invadir até concluir o trabalho

Em grande medida, sim (desculpe).

Abordagens que você pode considerar:

  1. Tente descobrir o que o código deve fazer, em termos comerciais.
  2. Leia toda a documentação que existe, não importa quão ruim seja.
  3. Converse com alguém que possa saber algo sobre o código.
  4. Percorra o código no depurador.
  5. Introduzir pequenas mudanças e ver o que quebra.
  6. Faça pequenas alterações no código para torná-lo mais claro.

Algumas das coisas que faço para esclarecer o código são:

  1. Execute um prettificador de código para formatar o código corretamente.
  2. Adicione comentários para explicar o que acho que isso pode fazer
  3. Altere os nomes das variáveis ​​para torná-las mais claras (usando uma ferramenta de refatoração)
  4. Usando uma ferramenta que destaca todos os usos de um símbolo específico
  5. Reduzindo a desordem no código - código comentado, comentários sem sentido, inicializações variáveis ​​sem sentido e assim por diante.
  6. Altere o código para usar as convenções de código atuais (novamente usando as ferramentas de refatoração)
  7. Comece a extrair a funcionalidade em rotinas significativas
  8. Comece a adicionar testes sempre que possível (nem sempre possível)
  9. Livre-se de números mágicos
  10. Reduzir a duplicação sempre que possível

... e quaisquer outras melhorias simples que você possa fazer.

Gradualmente, o significado por trás de tudo isso deve ficar mais claro.

Quanto ao lugar para começar? Comece com o que você sabe. Sugiro entradas e saídas. Muitas vezes, você pode entender o que devem ser e para que são usados. Siga os dados pelo aplicativo e veja para onde eles vão e como são alterados.

Um dos problemas que tenho com tudo isso é a motivação - pode ser um trabalho árduo. Isso me ajuda a pensar em todo o negócio como um quebra-cabeça e a celebrar o progresso que estou fazendo, por menor que seja.

Kramii
fonte
2
Eu acrescentaria um pouco a isso - em termos de "hacking" - comece abordando os problemas que você tem agora, ou seja, fazendo o desenvolvimento necessário, tudo que você precisa entender é como fazer essas alterações. Ao aprender que você aprende sobre o estilo do código e aprende sobre pelo menos parte dele. O mais importante é que você se concentra - para adicionar esse recurso ou alterar essa funcionalidade ou qualquer outra coisa. Em seguida, ao fazer a alteração, você pode executar as etapas de refatoração (conforme descrito).
Murph
Ótima resposta. Eu tive a situação de entrar em um projeto desconhecido para mim. Fiz muitas limpezas, incluindo fontes, processo de compilação e assim por diante. Acho que nem todas as mudanças serão mantidas, mas isso ajudou no processo de orientação para mim.
gyorgyabraham
@Murph +1 por mencionar o foco. É muito importante ter em mente qual é o seu foco ao lidar com uma base de código complexa. E sim, estar interessado no estilo é tão importante.
smwikipedia
32

Sua situação é realmente comum. Qualquer pessoa que precise entrar em um novo trabalho em que exista código para trabalhar, irá lidar com algum elemento dele. Se o sistema é um sistema legado realmente desagradável, é muito parecido com o que você descreveu. Obviamente, nunca há documentação atual.

Primeiro, muitos recomendaram o trabalho eficaz com o código herdado de Michael Feathers. Este é realmente um bom livro, com capítulos úteis como "Não consigo colocar essa classe em um equipamento de teste" ou "Meu aplicativo não tem estrutura", embora às vezes o Feathers possa oferecer apenas mais simpatia do que solução. Em particular, o livro e seus exemplos são amplamente voltados para idiomas de chaves. Se você estiver trabalhando com procedimentos SQL retorcidos, pode não ser tão útil. Acho que o capítulo "Eu não entendo esse código o suficiente para alterá-lo" fala do seu problema. Feathers menciona aqui as coisas óbvias, como fazer anotações e marcar listagens, mas também enfatiza que você pode excluir código não utilizado se tiver controle de origem. Muitas pessoas deixam seções de código comentadas no lugar,

Em seguida, acho que sua abordagem sugerida é certamente um bom passo. Você precisa entender primeiro em alto nível qual é o objetivo do código.

Definitivamente, trabalhe com um mentor ou alguém da equipe, se você precisar responder às perguntas.

Além disso, aproveite a oportunidade para oferecer suporte ao código se os defeitos forem revelados (embora às vezes você não precise se voluntariar para isso ... o defeito o encontrará!). Os usuários podem explicar para que eles usam o software e como o defeito os afeta. Geralmente, esse conhecimento pode ser muito útil ao tentar entender o significado do software. Além disso, entrar no código com um alvo intencional para atacar às vezes pode ajudar a focar você quando enfrentar "a fera".

Bernard Dy
fonte
13

Eu gosto de fazer o seguinte quando tenho um arquivo de origem muito grande:

  • Copie toda a bagunça na área de transferência
  • Cole no Word / companheiro de texto qualquer
  • Reduza o tamanho da fonte ao mínimo.
  • Role para baixo olhando para os padrões no código

Você ficaria surpreso com o quão estranhamente familiar o código parece quando você volta ao seu editor normal.

sal
fonte
Isso começou a se tornar mais comum desde 2011 e agora são várias abordagens / ferramentas (eu poderia encontrá-las agora, mas sei que elas existem) que podem fornecer contornos e contagens de alto nível de várias coisas no código para dar uma impressão visual do código, por exemplo, número de linhas por classe, comprimento de cada linha, número médio de parâmetros por método, etc. Essas ferramentas agora estão sendo usadas por gerentes com centenas de desenvolvedores e milhões de linhas de código.
junky
O texto sublime possui um 'minimapa' que pode ser usado para uma finalidade semelhante.
kmoe
12

Leva tempo

Não se sinta muito apressado ao tentar entender uma base de código herdada, especialmente se estiver usando tecnologias / linguagens / estruturas com as quais você não está familiarizado. É apenas uma curva de aprendizado inevitável que leva algum tempo.

Uma abordagem é ir e voltar entre o código e os tutoriais sobre as tecnologias relacionadas. Você lê / assiste o tutorial e, em seguida, analisa o código para ver como seus antecessores o fizeram, observando semelhanças e diferenças, anotando e fazendo perguntas a qualquer desenvolvedor existente.

"Por que você fez essa parte dessa maneira"

"Percebi que a maioria das pessoas on-line está fazendo dessa maneira, e todos vocês fizeram de outra maneira. Por que isso?"

"O que fez todos vocês escolherem a tecnologia X em vez da tecnologia Y?"

As respostas a essas perguntas ajudarão você a entender o histórico do projeto e o raciocínio por trás das decisões de design e implementação.

Eventualmente, você se sentirá familiarizado o suficiente para começar a adicionar / consertar coisas. Se tudo parece confuso ou parece haver muita "mágica" acontecendo, você não passou tempo suficiente examinando, digerindo e fazendo diagramações. Criar diagramas (diagramas de sequência, diagramas de fluxo de processos etc.) é uma ótima maneira de entender um processo complexo, além de ajudar o "próximo indivíduo".

CFL_Jeff
fonte
9

O cscope pode fazer o que ctags pode fazer por C, além disso, também pode listar onde todas as funções atuais são chamadas. Além disso, é muito rápido. Escala facilmente para milhões de LOC. Integra-se perfeitamente ao emacs e vim.

Contador de código C e C ++ - o cccc pode gerar métricas de código no formato html. Eu usei wc também para obter LOC.

doxygen pode gerar sintaxe destacada e código de referência cruzada em html. Útil na navegação por grandes bases de códigos.

aufather
fonte
8

A maneira como recomendo o Drupal e não é realmente específico do Drupal: comece com o rastreador de problemas. Certamente haverá relatórios de erros antigos e não fechados. Você pode reproduzi-los? Se sim, atualize o ticket confirmando-o. Se não, feche-o. Você encontrará desta maneira várias maneiras de usar o software e poderá começar a espreitar a base de código onde ele trava. Ou você pode começar a percorrer o código e ver como ele chega aonde ele falha. Dessa forma, você não apenas começará a entender a base de código, mas também acumulará uma tonelada de karma e suas perguntas serão muito bem recebidas pela comunidade.

chx
fonte
6

Uma coisa importante a fazer é usar ferramentas para gerar gráficos de dependência para explorar de cima para baixo a arquitetura de código. Primeiro visualize o gráfico entre os assemblies ou jars .NET. Isso dará uma idéia de como os recursos e as camadas são organizados e, em seguida, analise as dependências dos espaços para nome (dentro de um ou alguns assemblies ou jars .NET parentes) para ter uma idéia mais refinada do código estrutura e, finalmente, você pode examinar as dependências das classes para entender como um conjunto de classes colabora para implementar um recurso. Existem várias ferramentas para gerar gráfico de dependência, como o NDepend for .NET, por exemplo, que gerou o gráfico abaixo.

insira a descrição da imagem aqui

Patrick Smacchia - desenvolvedor NDepend
fonte
6
Existem inúmeras ferramentas que podem criar gráficos de dependência legíveis com algum tipo de hierarquia, mas isso não parece ser um deles. Também trabalho com design eletrônico, e para isso existe uma regra de ouro (literalmente): se eu tiver que seguir uma linha do seu esquema com o dedo a qualquer momento, é um esquema ruim.
5

Certa vez, um engenheiro de software bastante fantástico me disse que a forma mais cara de análise e manutenção de código era percorrer o código, linha por linha; é claro, somos programadores, e isso praticamente vem com o trabalho. A mídia feliz, eu acho, é (nesta ordem): 1. Pegue um bloco de notas para criar notas sobre como você entende o código para funcionar e adicione-o com o passar do tempo 2. Consulte a documentação sobre o código 3. Converse com autores ou outras pessoas que deram suporte à base de código. Peça a eles um "despejo cerebral" 4. Se você está no ponto em que entende algumas das relações de classe no nível de detalhe, faça uma depuração passo a passo do código para fazer uma síntese entre como você achou que o código funcionava e como o código realmente funciona.

Tim Claason
fonte
5

Primeiro, entenda o que ele deve fazer - sem isso é provável que seja algo sem sentido. Fale com os usuários, leia o manual, o que for.

Em seguida, pressione run e comece a percorrer o código para o que parecem ser as principais funções.

Jon Hopkins
fonte
3

Dividir e conquistar. Olho cada funcionalidade e o código associado, passo por eles e continuo para o próximo, construindo lentamente uma imagem do todo.

Se o projeto teve testes de unidade, eu também gosto de passar por eles, eles são sempre muito reveladores e esclarecedores.

aredkid
fonte
3
  1. Execute todos os testes, se houver, e veja qual código é coberto e o que não é.
  2. Se o código que você precisa alterar não estiver coberto, tente escrever testes para cobri-lo.
  3. Mude o código. Não quebre os testes.

Veja Michael Feathers ' trabalhando efetivamente com o código legado

Kevin Cline
fonte
3

Aqui está minha pequena lista:

  1. Se possível, peça a alguém para fornecer uma visão de alto nível do código. Quais padrões foram considerados, que tipo de convenções eu poderia esperar ver etc. Isso pode ter algumas rodadas, pois no começo eu recebia uma história que, à medida que me familiarizava com o código, eu poderia ter novas perguntas perguntar enquanto eu trabalho na cebola do projeto preexistente.

  2. Execute o código e veja como são os sistemas. Concedido que pode ter mais do que alguns bugs, mas isso pode ser útil para ter uma idéia do que ele faz. Não se trata de alterar o código, mas apenas de ver como isso funciona. Como várias peças se encaixam para formar um sistema global?

  3. Procure testes e outros indicadores da documentação básica que possam ajudar na construção de um modelo mental interno do código. É aqui que eu provavelmente sugeriria pelo menos alguns dias, a menos que haja muito pouca documentação e testes, é claro.

  4. Como conheço bem os idiomas e as estruturas usadas neste projeto? A importância aqui é a diferença entre olhar para algumas coisas e dizer: "Sim, já vi isso uma dúzia de vezes antes e a conheço bastante bem" e "O que está sendo tentado aqui? Quem pensou que era uma boa idéia?" tipo de perguntas que, embora eu não as diga em voz alta, eu as estaria pensando especialmente se eu estiver olhando um código legado que pode ser bastante frágil e as pessoas que o escreveram não estão disponíveis ou simplesmente não se lembram do porquê as coisas foram feitas do jeito que eram. Para novas áreas, pode valer a pena gastar um tempo extra para conhecer qual é a estrutura e quais padrões posso encontrar neste código.

Por último, mas não menos importante: conheça as expectativas daqueles que estão executando o projeto em termos do que você deve fazer a cada momento, considerando as poucas idéias a seguir do que pode ser esperado:

  • Você está colocando em novos recursos?
  • Você está corrigindo bugs?
  • Você está refatorando o código? Os padrões são novos para você ou são muito familiares?
  • Você deveria estar apenas se familiarizando com a base de código?
JB King
fonte
2

Eu sempre tento começar com o ponto de entrada no programa, pois todos os programas têm um (por exemplo, método principal, classe principal, init, etc). Isso me indicará o que é iniciado e, às vezes, como as coisas estão vinculadas.

Depois disso, eu me aprofundar. O banco de dados e o DAO estão configurados em algum lugar, então eu entendo como as coisas são armazenadas. Talvez algum tipo de classe de instância global seja iniciada também, e aí eu posso descobrir o que está sendo armazenado. E com boas ferramentas de refratores, posso descobrir quem chama o quê.

Em seguida, tento descobrir onde a interface está configurada e manipulada, já que este é o próximo ponto de entrada de informações. As ferramentas de refração, pesquisa e depuração ajudam na minha pesquisa. Posso então descobrir onde o tratamento das informações começa e termina, percorrendo todos os arquivos de classe.

Depois, tento escrever o fluxo em algum papel, apenas para inicialmente envolver minha cabeça em torno das coisas. O botão enviar passa para a verificação genérica que é passada para o DAO ou banco de dados e é armazenada no banco de dados. Essa é uma simplificação grosseira da maioria dos aplicativos, mas é a ideia geral. Caneta e papel são extremamente úteis aqui, pois você pode anotar tudo rapidamente e não precisa se preocupar com a formatação de um programa que deveria ajudá-lo.

TheLQ
fonte
2

Eu diria para começar com a documentação, etc., mas, na minha experiência, a profundidade da documentação e do conhecimento local geralmente é inversamente proporcional à idade, tamanho e complexidade de um sistema.

Dito isto, eu geralmente tento identificar alguns threads funcionais. Por funcional, quero dizer coisas como efetuar login, obter uma lista de clientes, etc. Se os padrões forem consistentes, um encadeamento deve fornecer uma seção interessante, não necessariamente completa, do sistema. A melhor maneira de determinar se os padrões são consistentes é analisar um punhado de threads.

Eu acho que isso é desnecessário, mas, na minha opinião, é melhor entender o sistema de uma perspectiva funcional e não de uma perspectiva técnica. Geralmente, não me preocupo muito com as ferramentas que estão sendo usadas (ORMs, bibliotecas de log etc.) e me concentro mais nos padrões (MVP etc.) que estão sendo usados. Na minha experiência, as ferramentas geralmente são mais fluidas que os padrões.

Casey
fonte
2

Eu fiz muito ...

Aqui está minha abordagem atual para situações em que "algo está funcionando" e você precisa fazê-lo "funcionar de outra maneira".

  1. Obter objetivos, que o sistema deve resolver (se não estiverem escritos) - escreva-os. Pergunte ao gerente, outros funcionários, mesmo ex-funcionários, se disponíveis. Peça ao cliente ou pesquise qualquer documentação.
  2. Seja específico. Se não existir - escreva-o. Não vale a pena pedir a alguém, como se não existisse, então você está em situação em que outros não se importam muito. Então, apenas uma maneira de escrever o próprio (mais tarde será muito mais fácil se referir a ele).
  3. Obtenha design. Não existe - escreva. Tente consultar os documentos e o código-fonte o máximo possível.
  4. Escreva um projeto detalhado para a peça que você precisa alterar.
  5. Defina como você o testará. Portanto, você pode ter certeza de que o código antigo e o novo funcionam da mesma maneira.
  6. tornar o sistema capaz de ser construído em uma única etapa. E teste com código antigo. Coloque-o no SVC, se ainda não estiver.
  7. Implementar mudanças. Não mais cedo.
  8. depois de mais ou menos um mês, verifique se nada está quebrado.

Mais um trabalho opcional que pode exigir entre cada etapa: desatender o gerente (proprietário do projeto) que lhe diz que "essas alterações devem ser feitas já ontem". Após alguns projetos, ele pode até começar a ajudar a obter especificações e documentos com antecedência.

Mas geralmente (especialmente para scripts) simplesmente não é possível no escopo de negócios (o custo será muito alto, enquanto o valor será baixo). Uma opção é não fazer nenhuma alteração até que a massa crítica seja atingida e o sistema saia da produção (por exemplo, um novo sistema será lançado) ou a gerência decidiu que tudo isso vale a pena fazer.

PS: Lembro-me de um código que foi usado para 5 clientes com configurações diferentes. E cada alteração (novo recurso) era necessária, pensando em "quais peças são usadas" e "quais clientes de configuração", para não frear nada e não para o código de copypaste. Colocar suas configurações no projeto cvs e escrever especificações reduz esse tempo de reflexão quase para 0.

Konstantin Petrukhnov
fonte
2
Sinto muito, não acho que contratar um gerente ou proprietário de projeto em um novo emprego funcione bem para você. Eu estive exatamente na mesma situação e todas as pessoas se preocupam no início com resultados, resultados, resultados. Produza resultados e então você terá a chance de mudar a mente das pessoas, porque agora elas sabem que você é um trabalhador capaz, capaz de fazer o trabalho. Sugira melhorias e você poderá ser ouvido. Não o contrário, você será demitido antes do término do período de avaliação.
andre
11
Existem muitas maneiras de fazer isso educadamente. Por exemplo, escreva uma estimativa de que as mudanças diretas levarão 30 horas e outras estimativas de acordo com este plano: 50 horas. No segundo caso, ter objetivos, especificações e design economizarão muito tempo para alterações futuras. Se o gerente não estiver disposto a entender, provavelmente você não poderá mudar isso no futuro e trabalhará permanentemente com bolas de barro. Pode ser que é um bom indicador para encontrar outro emprego, então? Se ele aceitar o plano, apenas mostre a ele onde você está, quando ele pedir "resultados, resultados, resultados".
Konstantin Petrukhnov
2

Imprima o código fonte e comece a ler. Se for especialmente grande, imprima apenas partes selecionadas para entender melhor e faça quantas anotações / comentários forem necessários.

Rastreie o programa a partir do início de sua execução. Se você estiver atribuído a uma parte específica da base de código, rastreie a execução nessa parte e descubra quais estruturas de dados são usadas.

Se você estiver usando uma linguagem orientada a objetos, tente criar um diagrama de classes geral. Isso lhe dará uma boa visão geral de alto nível.

Infelizmente, no final, você terá que ler o máximo de código possível. Se você tiver sorte, os programadores anteriores escreveram o máximo de documentação possível para ajudá-lo a entender o que está acontecendo.

Rudolf Olah
fonte
2

A primeira coisa que você precisa fazer ao aprender uma nova base de código é aprender sobre o que ele deve fazer, como é usado e como usá-lo. Em seguida, comece a examinar a documentação de arquitetura para aprender como o código é organizado, e também como o banco de dados neste momento. Ao mesmo tempo em que você está aprendendo a arquitetura, é um bom momento para revisar qualquer fluxo de processo ou documentos de caso de uso. em seguida, comece a mergulhar e a ler o código depois de entender o panorama geral, mas apenas o código relacionado a qualquer trabalho que você esteja fazendo nesse código, não tente ler todo o código. É mais importante saber onde o código deve executar o X do que exatamente como o X é feito, o código está sempre lá para mostrar como você pode encontrá-lo.

Acho que apenas tentar pular e ler código sem um objetivo além de aprender o código geralmente não é produtivo, tentar fazer pequenas alterações ou revisar o código das alterações de outra pessoa é um uso muito mais produtivo do seu tempo.

Ryathal
fonte
2

Se uma base de código for grande, concentre sua atenção nas partes que estão trabalhando atualmente. Caso contrário, você se sentirá sobrecarregado e, possivelmente, sua cabeça poderá explodir. Eu acho que alguma visão geral de alto nível é útil (se estiver disponível), mas é provável que você gaste muito tempo no depurador para seguir o fluxo do programa. É uma boa idéia obter uma visão geral do aplicativo e vê-lo sendo usado, para que você possa entender como / para quê / por que o código está sendo usado.

Normalmente, eu executo algum tipo de ferramenta de complexidade de código no código para me dizer onde estão as áreas problemáticas. Áreas com alta pontuação provavelmente são muito difíceis de atualizar. Por exemplo, eu me deparei com uma função que tinha 450 pontos na escala ciclomática. Com certeza, centenas de FIs. Muito difícil de manter ou mudar isso. Então esteja preparado para o pior.

Além disso, não tenha medo de fazer perguntas aos desenvolvedores existentes, principalmente se eles trabalharem no sistema. Mantenha seus pensamentos internos para si mesmo e concentre-se em resolver os problemas. Evite comentários que possam deixar os outros desenvolvedores chateados. Afinal, pode ser seu bebê e ninguém gosta de saber que seu bebê é feio.

Dê pequenos passos, até a menor alteração de código pode ter um grande impacto.

Eu acho que é útil criar fluxos de código de programa, portanto, se estou fazendo alterações, posso fazer pesquisas de dependência para ver quais métodos / funções chamam o que. Suponha que eu esteja mudando o método C.

Se apenas 1 método / função chama C, é uma mudança bastante segura. Se centenas de métodos / funções chamarem C, isso terá maior impacto.

Esperamos que sua base de código esteja bem arquitetada, escrita e mantida. Nesse caso, levará algum tempo para entendê-lo, mas eventualmente a maré mudará.

Se for uma grande bola de barro, você nunca poderá entender (ou querer entender) seu funcionamento interno.

Jon Raynor
fonte
2

Algumas coisas que eu faço ...

1) Use uma ferramenta de análise de origem, como o Source Monitor, para determinar os vários tamanhos de módulo, métricas de complexidade etc. para ter uma ideia do projeto e ajudar a identificar as áreas que não são triviais.

2) Pesquise o código de cima para baixo no Eclipse (é bom ter um editor que possa procurar referências etc.) até que eu saiba o que está acontecendo e onde na base de código.

3) Ocasionalmente, desenho diagramas no Visio para obter uma melhor imagem da arquitetura. Isso também pode ser útil para outras pessoas no projeto.

JeffV
fonte
1

Isso acontece muito. Até começar a trabalhar em uma plataforma de código aberto, acho que nunca comecei um trabalho que não começou com a admissão de que o código tinha algumas 'peculiaridades'.

Você pode percorrer um longo caminho com um depurador de etapas e muita tenacidade. Infelizmente, muitas vezes é preciso tempo e experiência para aprender uma grande bola de barro em particular e, mesmo assim, depois de anos, ainda pode haver algum subsistema que surge, do qual ninguém tem conhecimento.

Jeremy French
fonte
1

Eu o encorajo a escrever testes de unidade antes de mudar qualquer coisa na bola de barro. E apenas mude o código o suficiente no momento para fazer os testes passarem. Ao refatorar, adicione testes de unidade antes da mão para que você saiba que a funcionalidade do negócio não foi prejudicada pela refatoração.

A programação em pares é uma opção? Ter outra pessoa para trocar idéias é uma ótima idéia para lidar com essa quantidade desagradável.

David Weiser
fonte
Um dos problemas de uma grande bola de lama é que ela não possui limites adequados para escrever testes de unidade. Depois de chegar ao ponto em que você pode realizar o teste de unidade corretamente, você praticamente venceu.
Donal Fellows
Mas, se você está começando a modificar o código, ainda deve ter testes de unidade, para saber quando concluiu a correção.
David Weiser
1

Aqui está um procedimento que usamos para eliminar duplicatas.

  • selecione um prefixo de comentário padrão para duplicatas (usamos [dupe]logo após o marcador de comentário;
  • escreva especificações com suas equipes sobre nomes a serem usados ​​no procedimento duplicado;
  • primeira rodada: todo mundo pega alguns arquivos e os adiciona [dupe][procedure_arbitrary_name]antes do procedimento duplicado;
  • segunda rodada: todo mundo adota um procedimento, ou um subconjunto de procedimentos, e atribui um valor indicando a ordem de simpatia das diferentes implementações de mesma finalidade (a sequência será:) [dupe][procedure_arbitrary_name][n];
  • terceira rodada: o responsável por cada procedimento o reescreve na classe relevante;
  • quarta rodada: grepfeliz!
cbrandolino
fonte
1

Acho que uma das coisas mais importantes é pegar um recurso simples, escolher o mais simples possível e implementá-lo. Se houver uma lista de desejos mantida, use-a ou fale com alguém familiarizado com a base de código e peça-lhe que sugira um recurso. Normalmente, eu esperaria que isso fosse uma alteração com 5 ~ 20 LOC. O ponto importante não é que você esteja adicionando um recurso muito sofisticado, mas que esteja trabalhando (ou melhor, lutando :)) com a base de código e passando por todo o fluxo de trabalho. Deverias ter

  1. Leia o código para entender o componente que você está modificando
  2. Altere o código e entenda como isso afeta o sistema circundante.
  3. Teste a mudança e, assim, identifique como os componentes interagem entre si
  4. Escreva o caso de teste e, esperançosamente, quebre um ou dois casos de teste para consertá-los e entender os invariantes do sistema.
  5. Crie a coisa ou veja o IC construí-la e depois enviá-la

A lista continua, mas o ponto é que um mini projeto como esse leva você a todos os itens da sua lista de verificação para se familiarizar com um sistema e também resulta em uma alteração produtiva.

Osada Lakmal
fonte
1

Uma coisinha que eu queria acrescentar:

Uma ferramenta que comecei a usar recentemente para esse tipo de problema que ajudou imensamente é o mapeamento mental. Em vez de tentar entender todos os detalhes de como algo é implementado na minha cabeça, construirei um mapa mental descrevendo como o sistema pelo qual estou passando funciona. Isso realmente me ajuda a compreender mais profundamente o que está acontecendo e o que ainda preciso descobrir. Também me ajuda a acompanhar o que preciso mudar em uma escala muito precisa.

Eu recomendo usar o avião livre entre as inúmeras opções de mapeamento mental.

c.hughes
fonte
1

Não haverá documentação ou documentação escassa ou desatualizada. Encontre toda a documentação que existe. Se estiver em um repositório de equipe, não faça uma cópia. Caso contrário, coloque-o lá e peça permissão ao seu gerente para organizá-lo, talvez com alguma supervisão.

Coloque tudo no repositório da equipe e adicione um glossário. Todas as bases têm jargão; documentá-lo no glossário. Faça seções para ferramentas, produtos, específicos do cliente, etc.

Crie / atualize um documento de criação de ambiente de software. Todas as ferramentas, peculiaridades, opções de instalação etc. vão aqui.

Em seguida, faça upload de um documento Introdução ao "NomeDoProduto" ou algo semelhante. Seja apenas o fluxo da mente e se auto-organize ao longo do tempo. Em seguida, analise os documentos desatualizados e recupere-os. Os outros desenvolvedores vão gostar, você estará contribuindo de uma maneira única enquanto aprende o código. Documente especialmente todas as coisas que te surpreendem ou que são nomeadas erradas ou são contra-intuitivas.

Quando sua curva inclinada estiver chegando ao fim, não se preocupe em atualizar a documentação. Deixe o próximo cara novo fazer isso. Quando ele chegar, aponte-o para o seu trabalho. Quando ele continuamente lhe pede respostas, não responda. Em vez disso, adicione a pergunta à sua documentação e entregue a ele o URL. Vara de pescar.

Um efeito colateral é que você criou uma ferramenta que você mesmo pode fazer referência daqui a meses, quando esquecer.

E, embora não seja documentação, um problema relacionado são os pequenos procedimentos peculiares e intensivos manualmente que seus colegas de equipe fazem. Automatize-os com lotes, scripts sql e similares e compartilhe-os também. Afinal, o conhecimento processual é indiscutivelmente tão grande quanto o conhecimento declarativo em termos de produtividade em um novo ambiente. Seja o que for, não faça; em vez disso, faça o script e execute o script. A vara de pescar ataca novamente.

toddmo
fonte
1

Eu escrevi um post bastante longo sobre este tópico. Aqui está um trecho

Eu pensei sobre esse problema por um bom tempo. Decidi escrever minha própria solução pessoal como um processo geral. As etapas que documentei são as seguintes:

  1. Criar folha de vocabulário
  2. Aprenda a Aplicação
  3. Navegue pela documentação disponível
  4. Faça suposições
  5. Localizar bibliotecas de terceiros
  6. Analisar código

Esse processo é escrito no contexto de um aplicativo de desktop grande, mas as técnicas gerais ainda são aplicáveis ​​a aplicativos da Web e módulos menores.

retirado de: Um processo para aprender uma nova base de código

Lars
fonte
1

Existem algumas pequenas dicas que posso compartilhar.

Para um produto existente, começo a testá-lo intensivamente. Se escolher / receber uma tarefa, vou focar mais no recurso específico.

  • O próximo passo seria encontrar o código onde eu possa entrar e começar a explorar. No caminho, vou encontrar os módulos, bibliotecas, estruturas etc.

  • O próximo passo seria criar um diagrama de classes simples com suas responsabilidades (como cartões CRC)

  • Comece a fazer pequenas alterações ou consiga pequenos erros para corrigir e confirmar. Para que possamos aprender o fluxo de trabalho do projeto; não apenas o código. Geralmente, os produtos de grande porte têm algum tipo de contabilidade para fins de autorização e auditorias (por exemplo, projetos de assistência médica)

  • Converse com as pessoas que já estão trabalhando no projeto. Expresse suas idéias, pensamentos e, em troca, obtenha suas experiências e pontos de vista sobre o trabalho com este projeto por um longo tempo. Isso é muito importante, porque isso também ajuda você a se dar bem com a equipe.

sarat
fonte
1

Já faz muito tempo que eu tive que mergulhar em uma grande base de código. Mas, nos últimos anos, tentei várias vezes incluir novos desenvolvedores em equipes nas quais tínhamos uma base de código já bastante grande.

E o método que usamos com sucesso, e eu diria que é a maneira mais eficaz, sem questionar o IMHO, é a programação em pares.

Nos últimos 12 meses, tivemos quatro novos membros para a equipe e, a cada vez, o novo membro fazia pareamento com outro membro bem familiarizado com a base de código. No começo, o membro mais velho da equipe teria o teclado. Após cerca de 30 minutos, passaríamos o teclado para o novo membro, que trabalharia sob a orientação do membro mais velho da equipe.

Este processo provou ser bastante bem sucedido.

Pete
fonte
Sim, posso ver que um diálogo entre duas pessoas e uma base de código pode ser muito útil. O diálogo obriga a pensar em voz alta, o que de outra forma pode permanecer algum tipo de suposição.
Miku