Programadores e códigos legados. Agir como profissional ou apenas ignorar?
Provavelmente você já se deparou com o termo “código legado”. Para alguns dev’s esse termo pode despertar sentimentos muito diferentes como: Indiferença, tristeza, espanto ou até mesmo alegria. Ué mas legado não é coisa ruim? Como pode ser alegria? Em todas as áreas existem Profissionais e profissionais. Aqueles com P maiúsculo são os que enxergam oportunidades de melhoria contínua e de aprendizado. Refatorar um legado pode ser uma oportunidade para se aperfeiçoar nas regras de negocio da empresa ( software ) e também em design de software. Aqueles com p minúsculo que fazem apenas o mínimo necessário para manter seu emprego e o salário a cada dia 5, choram, esperneiam, xingam no twitter ou tem um encontro com o capitão Nascimento e pedem para sair.
Mas o que de fato é um código legado?
A primeira coisa que nos vem a mente quando lemos ou ouvimos esse termo, remete a algo velho, do passado, obsoleto. Não existe uma resposta exata para essa pergunta, como existe para, quanto é 2 + 2? Mas quando se trata de código legado pode haver algumas respostas diferentes, mas todas seguindo no mesmo sentido de direção.
Para o autor Michel Feathers, que escreveu o livro Trabalho Eficaz com Código Legado,
um código legado seria aquele que não possui testes.
Apesar desse livro ser de 2004 muitos de seus conselhos continuam válidos mesmo depois de quase 20 anos de seu lançamento.
Para outras pessoas o fato de ter escrito o código a algumas semanas ou meses já o torna legado, ou simplesmente alguns devs mais egocêntricos podem dizer: Não fui eu que escrevi, logo isso é um legado.
Para mim código legado é aquele em que a equipe ou o dev já perdeu as esperanças ou a motivação de melhoria. Aquele código que tem um débito técnico tão alto que simplesmente todos somente ignoram e seguem a vida implementando um if aqui, outro ali, ou retirando algo. O famoso: Já que tá tudo zoado mesmo, deixa assim.
Para outras pessoas pode remeter não só a código bagunçado/velho, mas também a tecnologias mortas que já foram descontinuadas, mas como o software escrito nesta tecnologia, continua colocando dinheiro no bolso do dono do software, pra que rescrever? Sites ou projetos que ainda rodam com php 5 e afins, por exemplo, desde que tenham recebidos tratamentos contra sqlinjection e outras vulnerabilidades, se não irão parar de funcionar de uma hora para outra nos browsers como os que usavam flash, para que vou reescrever?
Tendo visto tudo isso, podemos elencar algumas características de um código legado
- base de código relativamente antiga ainda em uso
- falta documentação (ou tem uma bastante pobre)
- autor(es) original(is) não podem ser encontrados( Devs que já saíram da empresa)
- falta testes
- não seguem boas práticas
- usa tecnologias que na maioria das vezes não estão em uso (difícil de encontrar especialistas)
Como avisar o gerente ( chefe ) ?
Penso que um ponto bem interessante é, como vou avisar meu chefe(gerente) sobre refatoração? Aquele famosa histórinha: Cara precisamos refatorar essa parte do projeto pois tá osso se achar nela.
Se o gerente for técnico, um “ ex-programador “ ( aquele que parou de codar, para virar gerente ) ou um cara que seja entusiasta de tecnologia esse processo se torna mais simples. Chame ele e mostre os pontos que precisam de uma refatoração, partes sensíveis do software referente a regras de negócio que são o core da aplicação. Mostre pra ele o quão difícil é as vezes encaixar um if no meio do algoritmo e como a escrita de testes para essa parte tornaria mais simples fazer as modificações do dia a dia.
Caso ele não seja técnico, não conte. Apenas faça. É basicamente o mesmo conselho que Martin Fowler da em seu livro Refatoração: Aperfeiçoando o Design de Códigos Existentes.
Como melhorar um código legado?
Nesse ponto creio que já temos uma noção do que pode ser um código legado, vamos agora traçar estratégias para atacar esse “problema” e deixar o código legado mais atraente.
Como você está de saco cheio com aquele código “macarrônico” sua primeira ideia é dar um delete no repositório e recomeçar tudo com a famosa v2. Mas ai você lembra que se fizer isso, seu emprego já era. Então a sanidade mental nos recomenda a partir para uma ação chamada Refatoração.
Mas o que é Refatoração?
Para Martin Fowler, refatoração é o processo de modificar um software de modo que não altere o comportamento externo do código, é uma maneira disciplinada de reorganizar o código minimizando as chances de introduzir bugs.
Agora pense um pouco, ao ler um algoritmo que está totalmente aninhado, com várias responsabilidades, nomes de variáveis poucos descritíveis, códigos repetitivos, e o fato dele não caber na tela sem ter que usar o scroll do mouse, você teria coragem de “meter a mão nele “ e fazer as alterações necessárias sem medo de que um novo bug seja introduzido ou alguma parte importante da regra seja esquecida ou alterada por engano ?
Se sua resposta for sim, lhe desejo boa sorte. Sua vida como dev desse projeto pode se tornar um pandemônio.
Caso a resposta seja não, Martin Fowler nos diz que o primeiro passo na refatoração é a escrita de testes.
“Toda vez que faço uma refatoração o primeiro passo é sempre o mesmo. Devo garantir que tenho um conjunto de testes robustos para o trecho de código.”
Inclusive uma reflexão interessante é que os testes podem servir como um detector de bugs, para proteger você de seus próprios erros.
Com base nisso, sabemos agora que o ideal é sempre começar por testes. Tendo em vista que o código não foi testado ainda, que é o cenário de muitos softwares legados por aí, que foram escritos na época em que pra muitos gestores escrever testes significava em perca de tempo hábil para por o projeto no ar. Se posso colocar uma feature no ar, em 2 dias, pra que irei acrescentar 1 dia a mais somente para pensar e escrever nos casos de testes ? TDD então nem pensar.
Um processo que sempre faço e inclusive Martin Fowler indica que seja feito em seu livro é o de fazer sempre pequenas modificações que permitam um ciclo de feedback rápido, ou seja, Refatorou um if ( por exemplo modificando clausura guarda para evitar uso indevido de else ) já faça logo o commit dessa alteração com uma mensagem bem clara do que feito. Isso permite que eu crie um histórico de toda refatoração que eu estou fazendo sendo assim ficando muito mais fácil eu retornar a um estado funcional caso tenha ocorrido algum erro.
Adquiri esse processo, quando descobri que o CTRL Z não conseguiu me salvar em uma alteração grande fiz. Como diz um certo grande filosofo. A sempre duas maneiras de se aprender. A primeira é se ferrando e a segunda é vendo os outros se ferrando . Nesse caso eu fui pelo caminho da primeira forma. Não sigam por ela.
Bom em breve estarei escrevendo um artigo que irá nos aprofundar nos tipos de refatoração existentes e formas de lermos um código e identificar pontos de melhoria e como fazer.
Dúvidas, pontos a serem acrescentados ou discutidos? Sinta-se a vontade de escrever e vamos trocar uma ideia sobre.
A maioria do código em uso é código legado. Um número minúsculo de vagas é aberto para construir um novo projeto. Praticamente desconsiderável.
Qualquer desenvolvedor que seguir carreira em algum momento vai ter que alterar um código legado e se virar, não tem como escapar.
V2 é impraticável
Imagine se o Banco do Brasil reescrever a base inteira de códigos sempre que ficar obsoleta. É impraticável. Quando acabasse uma versão os devs já deveriam começar uma nova.
Refatorar é a chave, mas nem sempre
Caso todo o código que for tocado tiver que ser refatorado também estaríamos fazendo um esforço impraticável. Já trabalhei em uma empresa que adotou uma cultura de refatorar para um novo padrão. A wiki de migração de uma classe era gigantesca, pq o padrão mudou dezenas de vezes nos mais de 25 anos daquele código. Tinham dezenas de padrões e o dev tinha que se virar com isso.
A chave está na comunicação
O que você e sua equipe decidiram? Vejo como papel do Tech Lead definir qual será o padrão de código atual, o que deve ser feito quando encontrar um código antigo que está fora desse padrão, e se naquele momento vale ou não o esforço.
Sabe a história do "não meche em time que está ganhando"? As vezes devemos fechar os olhos para o código antigo e entender que ele foi escrito em outra época, com outra mentalidade.
Se você olhar um código seu de 2 anos atrás e achar perfeito, você parou de evoluir!
Infelizmente às vezes só nos resta se contentar em trabalhar no código legado mesmo.
No caso da empresa em que trabalho, o cliente não quer trocar as máquinas para máquinas mais recentes, por isso temos que usar uma versão bem antiga do .NET (versão 2 e 3).
Além disso não quer depender de internet, daí salva os dados tudo em um monte de XML.
Essa é a justificativa que recebi. Já tentaram conversar e refatorar o código mas não deu muito certo.
Eu quando comecei tinha muito hype de novas tecnologias (.NET 8 chegou!), mas fui vendo que nas empresas não é assim que funciona. Só se eu trabalhar em consultoria e pegar algum projeto no início. Agora, se quiser uma empresa mais sólida, o código legado é inevitável. E muitas vezes não podemos simplesmente migrar.
Uma outra empresa que trabalhei tinha um legado gigante. A solução que encontraram é ir criando vários pequenos sistemas diferentes que substituem uma parte desse legado. Me parece uma ótima estratégia. Porque caso o sistema novo dê algum problema, o legado ainda está lá para salvar.