Práticas recomendadas para entregar o código herdado

66

Em alguns meses, um colega estará se mudando para um novo projeto e eu irei herdar um de seus projetos. Para me preparar, já encomendei o Trabalhando Efetivamente com o Código Legado de Michael Feathers.

Mas este livro, assim como a maioria das perguntas sobre o código legado que encontrei até agora, estão relacionadas com o caso de herdar o código como está. Mas neste caso eu realmente tenho acesso ao desenvolvedor original e nós temos algum tempo para uma entrega ordenada.

Algumas informações básicas sobre o código que herdarei:

  • Está funcionando: Não há bugs conhecidos, mas à medida que os requisitos de desempenho continuam aumentando, algumas otimizações se tornarão necessárias em um futuro não muito distante.
  • Não documentado: Existe praticamente zero documentação no nível de método e classe. O que o código deve fazer em um nível mais alto, entretanto, é bem compreendido, porque eu tenho escrito contra sua API (como uma caixa preta) por anos.
  • Somente testes de integração de nível superior: Existem apenas testes de integração testando a interação adequada com outros componentes por meio da API (novamente, caixa-preta).
  • Nível muito baixo, otimizado para velocidade: Como esse código é central para todo um sistema de aplicativos, muitos deles foram otimizados várias vezes ao longo dos anos e são extremamente de baixo nível (uma parte seu próprio gerenciador de memória para determinadas estruturas / registros).
  • Concorrente e livre de bloqueio: Embora eu esteja familiarizado com a programação simultânea e sem bloqueios e tenha contribuído com algumas peças para esse código, isso adiciona outra camada de complexidade.
  • Codebase grande: Esse projeto em particular tem mais de dez mil linhas de código, então não há como eu ter tudo explicado para mim.
  • Escrito em Delphi: só vou colocar isso lá fora, embora eu não acredite que a linguagem seja pertinente à pergunta, pois acredito que esse tipo de problema é agnóstico de linguagem.

Eu estava me perguntando como o tempo até sua partida seria melhor gasto. Aqui estão algumas ideias:

  • Obtenha tudo para criar na minha máquina: Mesmo que tudo deva ser verificado no controle do código-fonte, quem não esqueceu de fazer o check-in de vez em quando, então essa deve ser a primeira ordem de negócios.
  • Mais testes: Embora eu queira mais testes unitários em nível de classe para que, quando eu fizer alterações, qualquer bug introduzido possa ser detectado no início, o código como está agora não é testável classes, métodos longos, muitas dependências mútuas).
  • O que documentar: acho que, para começar, seria melhor concentrar a documentação nas áreas do código que, de outra forma, seriam difíceis de entender, por exemplo, por causa de sua natureza de baixo nível / altamente otimizado. Receio que existam algumas coisas que possam parecer feias e que precisem de refatoração / reescrita, mas na verdade são otimizações que estão aí fora por uma boa razão que eu posso sentir falta (cf. Joel Spolsky, Coisas que você nunca deve fazer, parte I )
  • Como documentar: eu acho que alguns diagramas de classe da arquitetura e diagramas de seqüência de funções críticas acompanhados por alguma prosa seria melhor.
  • Quem documentar: Eu estava me perguntando o que seria melhor, fazer com que ele escrevesse a documentação ou que ele me explicasse, para que eu possa escrever a documentação. Receio que as coisas que são óbvias para ele, mas não para mim, de outra forma não seriam cobertas adequadamente.
  • Refatoração usando programação em pares: Isso pode não ser possível devido a restrições de tempo, mas talvez eu possa refatorar alguns de seus códigos para torná-los mais fáceis de manter enquanto ele ainda estava por perto são do jeito que são.

Por favor, comente e adicione a isso. Como não há tempo suficiente para fazer tudo isso, estou particularmente interessado em como você priorizaria.

Atualização: Quando o projeto de entrega acabou, eu expandi essa lista com minhas próprias experiências em esta resposta abaixo .

    
por PersonalNexus 07.11.2011 / 20:44
fonte

11 respostas

25

Como você tem acesso ao desenvolvedor que você codifica, pergunte: -

  • Quais módulos foram os mais difíceis de codificar / implementar. Quais foram os problemas e como eles foram superados?

  • Quais módulos geraram mais bugs.

  • Quais módulos resultaram nos mais difíceis de resolver erros.

  • Que pedaços de código ele está mais orgulhoso.

  • Que pedaços de código ele realmente gostaria de refatorar, mas não teve tempo.

Essas perguntas lhe darão uma visão sobre o que causará mais problemas e, talvez mais importante, um controle sobre os processos de pensamento e perspectivas do desenvolvedor original.

    
por 08.11.2011 / 05:53
fonte
17

Quando o projeto de entrega acabou, acho que eu tomaria o tempo e escrevia minha própria resposta contendo as coisas que funcionavam melhor para mim.

  • Obtenha tudo sob controle de versão: Após garantir que tudo o que eu precisava para criar estivesse sob controle de versão, também procurei no disco rígido do desenvolvedor antigo para procurar scripts ou utilitários adicionais que seriam úteis para implantar e / ou testar o aplicativo, mas não foi verificado.
  • De cima para baixo: Eu começaria com uma visão de alto nível das principais turmas e uma visita guiada com o antigo desenvolvedor das principais áreas. Então eu cavaria mais fundo no resto sozinho, sinalizando coisas que não faziam sentido para mim com //TODO marcadores.
  • Escreva-me toda a documentação: Enquanto o antigo desenvolvedor olhava o meu texto para me certificar de que estava certo, insisti em escrever tudo sozinho. Dessa forma, eu teria certeza de que a escrita fazia sentido para mim e não apenas para o antigo desenvolvedor.
  • Comentários em todos os lugares: adicionei resumos da documentação em XML a todas as turmas e a todos os método. Dessa forma, assegurei-me de que, pelo menos, tivesse olhado para cada código e tivesse entendimento suficiente para resumir o que ele fazia em uma frase. Ele também facilitou o entendimento dos métodos usando métodos / classes de resumo, pois o IntelliSense coleta essas informações. Também consegui identificar facilmente as áreas do código que eu ainda precisava ver.
  • Documento próximo à fonte: Para facilitar a conexão entre o código-fonte e a documentação, coloco a maior parte da documentação no código-fonte. Para documentação de alto nível que descreve a interação entre vários subsistemas, usei um wiki, já que colocar essas informações em um único lugar no código não funcionava. Toda a documentação deve ser eletrônica e de texto completo pesquisável.
  • Diagramas: Para uma visão geral básica, usei diagramas de classes de várias granularidades para os diferentes subsistemas. Para as partes concorrentes, os diagramas de objetos e interação foram realmente úteis; veja também minha outra pergunta sobre o assunto .
  • Refatorando como um par: Embora tenha feito alguma refatoração com o antigo desenvolvedor para ter uma ideia do código e tornar as coisas mais fáceis de manter, esse processo foi demorado e arriscado, devido à falta de bons ferramentas de refatoração e um monte de dependências desagradáveis entre as várias partes. O trabalho do Michael Feathers em Efetivamente com o Código Legado é uma ótima ajuda para isso, mesmo que a refatoração sem o suporte adequado da ferramenta ainda seja dolorosa. Enquanto refatorava, eu o deixava controlar o mouse e o teclado, pois era mais divertido para ele (veja também meu último ponto) e eu estava livre para escrever o que eu estava aprendendo.
  • Check-ins separados para comentários e alterações: Depois que eu acidentalmente introduzi um bug escrevendo um comentário sobre um override , tomei o cuidado de fazer comentários e alterações em check-ins separados. Eu usei um pequeno utilitário para remover todos os comentários do código-fonte antes de verificar algo, então um diff de um check-in somente para comentários mostraria 0 diferenças. Todas as alterações (por exemplo, remoção de campos não utilizados) foram analisadas cuidadosamente por colegas com o antigo desenvolvedor para garantir que não removia as coisas que ainda eram necessárias.
  • Explicação passo-a-passo de passagens críticas: Para as passagens mais otimizadas / complexas, eu examinaria o código linha-por-linha com o desenvolvedor antigo e às vezes até com um terceiro colega. Dessa forma, obtive uma compreensão completa do código e, à medida que mais pessoas analisaram o código, na verdade identificamos alguns bugs, além de algumas coisas que poderiam ser otimizadas ainda mais.
  • Seja rápido e mantenha o antigo desenvolvedor motivado: notei que o antigo desenvolvedor estava cada vez menos interessado, pois seu último dia estava chegando mais perto (não surpreendentemente). Por isso, asseguraria que as partes mais críticas fossem entregues primeiro, deixando o resto para eu descobrir sozinha, se necessário. Eu também tentei deixar as coisas mais divertidas (por exemplo, o controle do teclado durante a programação em pares) para ele e fazer as coisas chatas, como documentação, escrevendo eu mesmo.
  • Identifique solicitações de recursos: achei útil perguntar ao antigo desenvolvedor uma lista de recursos que as pessoas solicitaram, mas que ainda não foram adicionadas. Havia algumas coisas que para mim pareciam simples de adicionar, mas onde havia uma boa razão para elas não serem adicionadas, pois teriam quebrado outras coisas quando implementadas da maneira que eu havia pensado no começo.
por 01.02.2012 / 21:55
fonte
14

Tendo passado por uma situação semelhante, acredito que o seguinte também merece consideração:

  • Certifique-se de fazer e testar uma implantação: faça sua própria implantação do produto, do zero - e verifique se isso é idêntico a um feito por a pessoa que está saindo. Isso garantiria que todos os scripts e instruções fossem claros para você e detectaria quaisquer descuidos acidentais, como se os ingredientes não tivessem sido registrados em seu sistema de controle de versão. (Não estou dizendo que isso aconteceria , apenas que se acontecer acontecer, será muito mais fácil lidar com isso agora, antes que a pessoa saia)

    (Isso pode não ser relevante para você, por exemplo, se você já faz Integração contínua ou Implantação contínua, mas vale a pena mencionar, apenas no caso ...)

  • Escrevendo mais testes: Essa é uma boa maneira de testar sua compreensão de um sistema. Isso permitirá (ou forçará) você a observar mais de perto as áreas do código e confirmará se o código é tão livre de bugs quanto você suspeitar ou revelará áreas em que você pensou que entendeu a intenção, mas na verdade você precisa pedir esclarecimentos ao seu colega antes de ele sair

  • Escrita em pares da documentação: Esta é uma maneira eficaz de escrever visões gerais. Estou sugerindo que você peça ao seu colega para descrever um recurso ou área, e então você escreve, na documentação, com suas próprias palavras. Descobrimos que isso era maciçamente mais fácil quando feito por duas pessoas juntas.

Eu colocaria a escrita dos testes como uma prioridade mais alta do que a escrita da documentação, pessoalmente, já que os testes provavelmente lhe darão mais - ou mais firme - compreensão.

Em relação a Refatoração usando programação em pares , a única coisa que eu diria é que há o perigo de que isso se torne um poço sem fundo, especialmente considerando que você disse que só tem alta testes de nível. Você pode achar que acaba usando muito mais tempo disponível do que você pretendia.

    
por 09.11.2011 / 22:38
fonte
10

+1 para as respostas que você já tem em sua pergunta!

Visita guiada
10k linhas de código é muito, mas eu acho que ainda não é impossível ter o outro cara te dando uma 'visita guiada'. Você se senta junto na frente do código e ele leva você em uma viagem de cima para baixo, trabalhando as "camadas". Você precisaria fazer isso em rajadas curtas - tudo de uma vez mataria vocês dois.

Zoom-in, zoom-out
A vantagem de fazer isso é que, enquanto ele está explicando isso para você, ele quase certamente terá alguns momentos "oh, sim, há isso também", que ele não poderia, se ele estivesse apenas tentando documentá-lo por conta própria. E suas perguntas ajudarão a focar nos bits óbvios para ele, mas não para ninguém. Esse tipo de interação de zoom in / zoom-out só é possível individualmente, tentando escrever ou ler algo assim é difícil.

Documentação
Eu acho que você deveria estar documentando as coisas de forma independente - ele deve começar no fundo (no caso de você não ter tempo de chegar lá junto), e você deve começar no topo, com base no que você entendeu visita guiada e como se fosse para outra pessoa [em um trabalho anterior eu herdei uma carga de código 'legado', e apenas tive tempo para documentá-lo antes de sair:]].

Onde está o quê?
O objetivo da maior parte disso é que você possa ter uma idéia de onde as coisas acontecem. Assim, dado um bug ou uma modificação específica, você pode rapidamente encontrar o lugar no código no qual você precisa se concentrar. Você pode testar a si mesmo pegando a lista de bugs antigos e verificando se consegue prever com precisão onde estava o problema.

Bombeie-o para secar
Não importa se ele acaba odiando você (sorriso), seu trabalho é obter o máximo de informação possível do cérebro desse cara no tempo disponível. Certifique-se de obter gerenciamento do seu lado e que eles priorizem a transferência de conhecimento "apenas consertando os últimos bugs antes que ele saia" (a menos que você esteja corrigindo-os juntos ...).

    
por 10.11.2011 / 08:49
fonte
7
Sugiro o seguinte (além do que já foi identificado) - Primeiro, peça ao seu gerente que lhe dê tempo para trabalhar com esse cara o máximo possível e tente sentar-se com ele sempre que ele for encarregado de fazer uma mudança. Você não precisa saber tudo o que ele está fazendo, mas tente pegar o máximo que puder. O mais importante é ser amigo dele.

Trate a transferência como um projeto e implemente um plano e envolva o gerenciamento.

0 - Certifique-se de saber como usar o sistema.

1 - Faça um inventário claro dos componentes da solução, a fonte de cada um e onde está (em repositórios de diferenças)

2 - Obtenha e, se possível, gerencie as senhas dos diferentes servidores a partir de agora. Verifique se você tem todas as informações da conta de administrador

3 - Obtenha as licenças de cada componente externo, a menos que esteja fora do seu escopo (por exemplo, dlls especiais, banco de dados, etc.)

4 - Obtenha um relatório por escrito sobre o status atual do sistema do desenvolvedor e de seus clientes (se eles forem locais da sua empresa)

5 - Obtenha a documentação das regras de negócios, fórmulas de cálculo, etc. Você pode fazer isso com ele. Peça a ele por e-mails, informações de reuniões, documentos de requisitos do usuário, documentos de design e similares a serem dados a você.

6 - Obtenha uma lista de eventos agendados (execuções mensais de trabalhos, execuções semanais de trabalhos) que o software deve responder a

7 - Aprenda os procedimentos de backup / restauração

8 - Compreender o (s) framework (s) usado (s) na construção do aplicativo

9 - Conheça as modificações solicitadas / esperadas / planejadas e o status de quaisquer solicitações de usuários pendentes. Comece a tentar identificar como fazer isso sozinho.

10 - Certifique-se de que seus ambientes de teste e desenvolvimento sejam muito semelhantes.

11 - Tente identificar as principais dependências (em outros sistemas ou entre componentes) que não podem ser facilmente identificadas.

12 - Identifique e documente as versões necessárias de cada uso de software e seu contato de fornecedor (se necessário)

13 - Identifique quaisquer ferramentas especiais que ele estivesse usando que você não tenha, caso isso possa ajudá-lo.

14 - Obtenha um fluxo de sistema de alto nível. e comece a construir sua biblioteca de documentação

15 - Entenda como gerenciar a segurança do usuário para o aplicativo

16 - Obtenha o registro de bugs e tente entender as ações e como a ação afetou os dados mais antigos (se aplicável)

17 - Conheça processos que demorem muito e o que você precisa observar (por exemplo, tamanhos incomuns de arquivos, ftp de arquivos duplicados, etc.), quando aplicável.

18 - Verifique o relógio do servidor de produção

19 - Identifique onde estão as configurações e compare cada configuração de ambiente com a produção para saber quais parâmetros são diferentes e por que

20 - Obtenha as informações de contato desse cara

21 - Se o sistema for interno, agende uma reunião com os usuários do sistema (você precisa saber quem eles são e qual o papel que cada um desempenha) e ser apresentado a eles. Ouça o que eles têm a dizer sobre o sistema e sobre seus problemas atuais, se houver. Verifique se você está incluído nos e-mails o mais cedo possível (após a aprovação do seu gerente)

22 - Avalie sua compreensão uma semana antes de ele sair e relate qualquer problema que você veja como um risco

Desde que você mencionou que você não tem um banco de dados, esta lista ficou mais curta.

Boa sorte.

    
por 11.11.2011 / 22:26
fonte
5

Eu consideraria as partes mais complicadas e otimizadas para desempenho primeiro. Eu pediria para ele primeiro documentar essas partes e explicá-las a você uma por vez, então eu tentaria escrever testes contra essas partes (incluindo antes e depois dos testes de desempenho, para que você possa ver se uma nova otimização melhora ou piora as coisas) ) e faça a outra pessoa rever os testes. Desta forma, ele documenta e explica, você usa a explicação para escrever testes (enquanto ele está documentando uma área diferente), e sua revisão ajudará a se certificar de que você entendeu o que deveria estar testando. Dessa forma, você também obtém uma média adicional de teste para algumas das partes mais críticas do aplicativo e da documentação das otimizações de desempenho especializadas.

Se houver tempo depois de cobri-los, passarei em seguida por um processo semelhante com as partes do aplicativo que mais frequentemente precisaram mudar ao longo dos anos, mas que não estão no primeiro grupo de coisas documentadas.

Em seguida, documente tudo o que resta.

    
por 07.11.2011 / 21:50
fonte
5

Acho que a melhor maneira de obter algum código grande é a abordagem de cima para baixo. Tente entender o quadro geral primeiro e, em seguida, vá mais fundo nos componentes, um a um.

Agora, em cada nível de escavação, peça a ele para priorizar as partes que precisam de mais atenção. Peça-lhe que o explique o máximo possível, mas sempre documente você mesmo.

A melhor parte de documentar você mesmo é que, quando voltar mais tarde, você não terá problema em lembrar o mesmo estado cognitivo em que estava, quando ele explicou a você. Você pode entender com mais facilidade o que você escreveu do que o que outra pessoa fez. Na minha experiência, duas pessoas que documentam o mesmo trecho de código não produzem textos de aparência semelhante.

Isso também resolve seu problema de "o que e como documentar". Quando ele explica tudo, você pode decidir o que deseja documentar quando voltar ao código - e documentar apenas essas partes.

A ideia é primeiro entender completamente o código (na sua presença), e depois escrever / fazer tudo o que lhe permitirá dar mais grana (na sua ausência).

Compreendendo completamente o código, quero dizer que você precisa ter uma ideia do quadro geral - e como cada componente se relaciona com esse quadro geral. Eu achei particularmente útil para acompanhar como cada peça soma o todo. Não tente compreender nada isoladamente - nunca perca a visão do contexto.

Finalmente, depois de ter feito o acima, tome o controle proativamente. Decida em que partes você precisa de cobertura de teste de unidade. que partes precisam ser (ou podem ser) otimizadas, como você pode refatorar algum componente, etc. Confie que, se você conhece o sistema, você pode tomar todas as decisões depois que ele for embora.

    
por 08.11.2011 / 07:33
fonte
5

Eu sinto por você.

Algumas sugestões:

  1. Grave todas as conversas que você tiver com o programador de saída!
  2. Peça a motivação por trás dos "grandes" problemas. É bom você entender a API, mas procure as decisões internas - por que o código foi particionado como está? Quais são as responsabilidades?
  3. Faça um esforço para realmente estudar o código. Quando você assume as tarefas de manutenção e suporte, às vezes há a pressão para "estudar o código enquanto progride". Resista se puder e realmente estude o código.
  4. Procure por cenários. Você conhece a API - veja como o código se comporta. Um exemplo que vem à mente é o de um módulo de fax. Como usuário da API, você pré-prepara teve que preparar uma imagem da página e enviar ao código um comando para transmitir a página. Peça ao programador que sair para rastrear com você o código para ver como esse cenário é realizado. Então, é claro, vá para o cenário "receber página".
  5. 80/20 - tente cobrir os cenários mais comuns primeiro.
  6. Considere uma reescrita. Se o código é antigo e as interfaces são bem definidas, talvez a tecnologia tenha mudado o suficiente para justificá-lo.
  7. Eu odeio dizer isso, mas considere procurar um novo emprego.
por 12.11.2011 / 19:50
fonte
3

Se você quiser uma documentação decente e razoavelmente indolor, compre uma cópia do Pascal Analyzer (PAL) Eu usei isso em projetos Delphi e foi ótimo - eles podem agora dividir a funcionalidade da documentação em um produto que eu não conheço (Pascal Browser), então você pode ter que comprar os dois (< 300 USD), mas o PAL foi uma ótima ferramenta para entender onde as variáveis estavam sendo usadas onde as funções estavam sendo chamadas de etc & pegando todos os tipos de possíveis problemas com o código.

Use o PAL para ter uma ideia de como o código é estruturado e, provavelmente, uma lista de cerca de 1000 sugestões de melhorias, se a minha experiência fosse alguma coisa para continuar. Trabalhar na lista melhorará a qualidade do código, simplificando-o e & torne sua vida mais fácil para o futuro. O próprio Delphi suporta a refatoração em versões recentes (nos últimos 5 anos ou mais). Você precisou incluir tudo no arquivo dpr para que ele realmente funcionasse corretamente quando eu estava fazendo isso, tenha isso em mente.

Se você quiser testes de unidade, faça o download DUnit & comece a criar alguns testes com o codificador original - essa é provavelmente uma maneira construtiva de usar pelo menos parte do tempo deles.

    
por 10.11.2011 / 09:33
fonte
2

Embora você não tenha mencionado sobre um banco de dados de back-end, mas supondo que haja um, você deve

  1. Obtenha o modelo de dados documentado especialmente as colunas e PK-FK
  2. Configure um sql trace e registre todas as consultas que são acionadas durante o uso do aplicativo. A ordem de execução das consultas lhe dará uma boa idéia sobre o fluxo do aplicativo e também ajuda na depuração
por 10.11.2011 / 19:13
fonte
2

Estou na mesma situação em que o nosso arquiteto mudou-se para a Austrália e deixou muito legado como estava com a empresa nos últimos 8 anos. Ele mesmo herdou coisas herdadas do Arquiteto anterior que era um contratado.

Você e outros já mencionaram pontos positivos, mas aqui estão os problemas que enfrentamos depois que ele saiu pode ser que você possa se preparar melhor ...

1) (Pessoa técnica) Detalhes de contato dos clientes com quem ele está lidando.

2) A conta dele debaixo da qual ele comprou licenças de softwares, chaves que precisam ser renovadas todos os anos e processos / custos para renovar eles.

3) Documento de configuração de bibliotecas / componentes de software de terceiros e produtos que se integram com seus produtos. Nós nos esforçamos por 4 dias para trazer de volta uma máquina que foi perdida devido à liberação de espaço e algumas instruções erradas que foram passadas para eles.

4) Documentos / etapas ele é usado para depositar o código-fonte em empresas de depósito de software, por exemplo, Custódia.

5) Ainda há uma lista longa, mas pode não ser aplicável a você também Nenhuma quantidade de documentação pode substituir uma pessoa real, então Mantenha seus detalhes à mão, fique em termos legais e boa sorte:)

Além disso, eu não sei se esta é a primeira vez para você. Para mim, trabalhei com 5/6 empregadores e sempre herdei código com documentação ruim ou nenhuma documentação. Então, junto com toda a documentação, fique positivo:)

    
por 12.11.2011 / 12:37
fonte