Como abordar a refatoração de um aplicativo Web existente?

11

Ultimamente, tenho lido e pensado bastante e chegado à conclusão de que talvez deva repensar minha estratégia de desenvolvimento da web. Estou fazendo muita programação on-the-fly e, nos 2 anos em que estou trabalhando em um aplicativo Web PHP, o que poderia ter começado como uma pequena ferramenta se tornou um grande projeto. Mas há uma tonelada de código herdado de mim e meu predecessor, um trecho de código que pode ter sentido na época, mas agora estou questionando a utilidade desse código na forma em que ele é realmente. Além disso, coisas como testes de unidade e desenvolvimento orientado a testes não estavam no meu escopo até recentemente.

Então, como você abordaria a refatoração do aplicativo Web? Quais seriam as coisas que eu deveria procurar e em que ordem? E o jogo do navegador versus o aplicativo da web funcional? Haveria então diferença na abordagem?

Eldros
fonte
4
Se não estiver quebrado, não conserte. Gaste mais tempo escrevendo testes e menos tempo fazendo alterações desnecessárias.
Macneil
Apenas por interesse. Qual idioma / tecnologias você usou para escrever seu aplicativo? Que tipo de site é esse? Consulte welie.com/patterns -> Contexto do design -> Tipos de sites
JW01
@ JW01 Eu uso PHP para lógica interna e AJAX para gerenciamento de exibição e validação de formulário. Isso seria uma variante do padrão de aplicativo baseado na Web, mas disponível apenas em um determinado ambiente, pois é uma ferramenta interna.
Eldros
Eu tinha uma imagem completamente diferente do seu aplicativo na minha cabeça quando respondi à pergunta. Você tem muito mais liberdade para alterar a API do que se fosse de domínio público.
JW01
@ JW01 Eu não queria ser muito específico, pois queria que essa pergunta fosse útil para outras pessoas também.
Eldros

Respostas:

6

Praticamente da mesma maneira que você aborda qualquer tipo de código legado. Você encontra uma peça que pode ser testada, escreve testes e refatora.

Se você não conseguir encontrar uma peça prontamente testável, precisará testá-la sem o arnês de segurança de um conjunto de testes; nesse caso, altere com muito cuidado algum código quase testável para que seja testável.

Código que não renderiza coisas para o navegador - código de "infraestrutura", modelos, itens que tocam em bancos de dados - pode ser um bom ponto de partida.

Edit: UI testing: Com o aviso de que tenho pouca experiência aqui, um amigo meu faz isso: ele executa um pedaço de código gerador de HTML. Em seguida, ele corta seu código e compara o código recém-gerado com a versão antiga (usando diff; ele não automatizou todo o caminho). Alterações no HTML significam que sua refatoração quebrou.

Frank Shearar
fonte
Como você recomendaria testar a parte "view" de um aplicativo herdado - IE, a parte HTML / JavaScript / CSS / etc? Concordo que o teste de unidade é o caminho a seguir, mas o teste do código do aplicativo parece difícil de automatizar.
Justin Ethier
ao criar testes para uma interface da web - comparar o HTML antigo com o novo HTML é uma maneira meio frágil de fazer as coisas. Costumo identificar a semântica de uma página da web e testar isso. Ou seja, pergunte "A impressão na Web (título da página, título, palavras-chave, links externos, formulários) mudou?" não "O HTML mudou?".
JW01
Você pode testar aplicativos da web com um 'navegador sem cabeça' - basicamente uma biblioteca que é para um teste de unidade o que é um navegador para um especialista em controle de qualidade. No mundo java, há HTMLUnit (java puro, independente) e WebDriver (controla remotamente um navegador real como o FireFox). Meu projeto tem um conjunto de centenas de testes escritos assim.
Tom Anderson
@ JW01 Você está absolutamente certo - é muito frágil. É ótimo para testar uma refatoração de maneira única: você pode verificar se a refatoração não alterou a saída, mas toda vez que você altera o HTML gerado, precisa salvar o "novo esperado" HTML.
Frank Shearar
10

Há um ótimo livro sobre isso chamado "Trabalhando efetivamente com o código herdado", de Michael Feathers. Vamos ser sinceros, todos temos código legado.

O principal é testar o novo código que você está criando. Como você precisa tocar em outros trechos de código, encontrará oportunidades para testá-los também. É um processo longo e lento, mas se você fizer isso sistematicamente, poderá realmente melhorar o produto em geral ao longo do tempo.

Marcie
fonte
3
"Vamos ser sinceros, tudo o que estamos fazendo é escrever hoje o software legado de amanhã". - Martin Fowler
Frank Shearar
3
  • Sim - os aplicativos da Web são diferentes dos sites

Eu os trataria separadamente. Se você tem uma parte do site que é simplesmente uma coleção de documentos (que são iguais para usuários anônimos e usuários logados) - então o melhor método de estruturação é muito diferente de um aplicativo Web que serve páginas dinamicamente diferentes para cada usuário. Divida essas duas partes do site em dois aplicativos / componentes e lide com cada parte de maneira diferente.

  • Comece a usar o controle de versão

Uma vez que seu código está sob controle de versão, você pode passar e, com confiança, remover todo o código desnecessário que você mantinha anteriormente 'apenas por precaução' etc. etc. Não sei como sobrevivi sem o controle de versão.

  • Reduza os infinitos

Se quatro URLs diferentes apontam para o mesmo recurso, o problema é muito maior. Você acaba lidando com uma quantidade infinita de URLs. Assim que puder, verifique se você possui uma política de Normalização de URL. Feito isso, você pode começar a anexar significados semânticos aos URLs e poder fazer pesquisas inversas de recurso para URL. Isso permite que você separe a 'impressão da web' dos 'recursos' do site.

Você deve se perguntar: "dado um URL, qual é a sua forma normalizada?". Depois de ter fixado isso. Então, mais de 50.000 URLs no seu site podem ser reduzidos, ou seja, 2.000. o que é muito mais fácil de entender e gerenciar em sua mente.

consulte: http://www.sugarrae.com/be-a-normalizer-a-c14n-exterminator/

  • Comece modelando 'o que é', não 'o que você quer que seja'

Se você estiver arrumando um site herdado, que não foi projetado com as melhores práticas em mente desde o início, é tentador pular de 'uma bagunça' para 'o design ideal'. Eu acredito que você precisa fazer isso em pelo menos duas etapas: 'mess' -> 'código legado bem modelado' -> 'novo código ideal com recursos adicionais'. Pare de adicionar recursos. Concentre-se em consertar a bagunça ou encapsulá-la atrás de uma camada anticorrupção. Só então, você pode começar a mudar o design para algo melhor.

Consulte: http://www.joelonsoftware.com/articles/fog0000000069.html

Veja: http://www.laputan.org/mud/

  • Colocá-lo em teste é uma boa ideia.

Crie uma suíte / estrutura de teste e comece a adicionar testes. Mas, é bastante complicado testar algum código legado. Portanto, não fique muito pendurado nisso. Contanto que você tenha a estrutura lá, você pode adicionar testes pouco a pouco.

Veja: http://www.simpletest.org/en/web_tester_documentation.html

  • Tenha coragem em suas convicções

A maior parte da literatura sobre as melhores práticas de desenvolvimento de software é centrada em desktop / Enterprise App Centric. Enquanto o site está em uma confusão, você lê esses livros e pode admirar a sabedoria que emana deles. Mas não esqueça que a maioria dessas práticas recomendadas foi acumulada em épocas anteriores à web / SEO se tornar importante. Você sabe muito sobre a web moderna, mais do que é mencionado em livros clássicos como POEA, Gof etc. Há muito o que tirar deles, mas não descarte completamente sua própria experiência e conhecimento.


Eu poderia continuar. Mas essas são algumas das coisas que escolhi ao refatorar um site antigo antigo para um novo e brilhante.

JW01
fonte
Bons links de referência!
Nilesh
2

Antes de fazer qualquer coisa, é melhor ter seu projeto no controle de origem. Dessa forma, você pode reverter alterações ou trabalhar em alterações importantes em uma ramificação separada, além de marcos de marcação.

Em seguida, escreva testes para qualquer código que você planeja alterar. Você não precisa fazer tudo de uma vez, escrevendo testes para tudo. Exatamente o que você planeja trabalhar imediatamente. A teoria diz que, dado tempo suficiente, a maior parte da base de código será coberta por testes. Observe que algumas refatorações são "seguras" sem testes - elas estão documentadas no livro do Código Legado mencionado anteriormente e, sem dúvida, em outros lugares.

Com os testes para uma seção do código, altere o código. Faça o que for necessário, desde que os testes ainda passem.

Mesmo com o código legado, você pode fazer TDD se fizer acréscimos ou alterações. Basta escrever os testes primeiro para as alterações previstas, vê-las falhar e depois fazer as alterações.

Algumas ferramentas podem ser úteis aqui. O NDepend pode apontar códigos altamente acoplados e outros odores. O NCover rastreia seus níveis de cobertura de código. O FxCop é essencialmente um verificador de correção de código, além do que o compilador faz. Todas essas são ferramentas úteis para um projeto de qualquer tamanho real, especialmente a variedade herdada.

Por fim, é um processo de várias etapas. Não tente fazer tudo de uma vez, apenas leve um pouco de cada vez.

Grant Palin
fonte
-2

Se é feio o suficiente para me irritar, é feio o suficiente para eu excluir a coisa toda e escrever uma gota em substituição.

Você descobrirá que, na maioria das vezes, leva a mesma quantidade de tempo para fazer isso, assim como sentar e andar na ponta dos pés em torno de uma bagunça desorganizada e não documentada e acariciá-la suavemente.

Sneakyness
fonte
2
Eu discordo (embora eu não tenha dado a você -1). joelonsoftware.com/articles/fog0000000069.html
JW01
11
É realmente uma decisão situacional demais para me defender com precisão. Talvez eu não faça isso quando estiver trabalhando em uma enorme biblioteca de Objective-C, no entanto, não tenho escrúpulos em escrever uma biblioteca javascript totalmente nova.
Sneakyness
Muito má ideia! Eu gostaria de ter lido o artigo de Joel Spolsky que o @ JW01 vinculou a 2 anos atrás antes de decidir reescrever um aplicativo PHP existente usando Angular & Bootstrap. Angular e Bootstrap são ótimas tecnologias, mas ainda estou tentando converter esse aplicativo antigo dois anos depois. Eu deveria ter modificado o aplicativo existente e não ter sido arrancado / substituído.
Zack Macomber
Eu concordo especialmente ao considerar seu comentário. "cenário" é a principal coisa que determina uma decisão. Você deve remover a enorme API que serve a toda a empresa? Quem sabe, há muito a considerar. Você gostaria de testar antes para testar depois. O artigo vinculado é muito linear, como se houvesse um tamanho único, mas e quando algo está com erros ou é realmente um código antigo? O artigo está realmente sugerindo que não deixemos o legado com um código mais novo, mais fácil de ler e manter? Não há preto e branco no mundo do desenvolvedor, apenas cenários e decisões #
James