Todos nós sabemos o que significa a qualidade de código. Mais o menos. Damos respostas um pouco diferentes quando devemos dizer se um determinado pedaço de código é de boa qualidade ou não. Há certos aspetos que a gente pode medir, alguns outros exigem julgamento estético ou a gente simplesmente deve seguir o seu próprio instinto. A gente pode ter regras e estratégias que os desenvolvedores devem obedecer…mas eu não consegui encontrar nem um só documento que explica corretamente como é o código de boa qualidade.
Eu definiria a concepção de qualidade dos códigos-fontes focando na questão se o desenvolvedor for capaz de comunicar as ideias dele a um outro desenvolvedor que irá ler o seu código. Isso inclui legibilidade, comentários concisos e precisos, uso de nomes significativos, organização de código, layout na superfície e componentização adequada em toda a hierarquia do aplicativo, interfaces claras e dependências profundas. Inerentemente, o código deve ser performático e livre de falhas (bugs, vulnerabilidades). E um código de aplicativo em seu próprio nível deve ser autodocumentado para alcançar a descrição acima.
Nós aqui da FreeSoft estamos no negócio de conversão de linguagens de programação; por exemplo, entrada Cobol, saída Java. Estamos a falando de Cobol que alguns caras escreveram há 20-30 anos atrás. Eu não vou avaliar essas partes de código agora – mas vamos dar uma olhada no que podemos dizer sobre o Java que a gente cria.
Semelhança ao legado
As linguagens legadas com as quais trabalhamos não são orientadas a objetos, mas devemos criar Java orientado a objetos apenas porque Java é inerentemente uma linguagem de OO. Durante a conversão, as nossas ferramentas criam classes que representam algum ‘significado’ no aplicativo legado. Normalmente um aplicativo de Cobol se transforma em uma classe de Java com métodos… oh!… caso aplicável.
Cada pedaço do código legado é tratado como (um conjunto de) objetos. Uma variável se transformará em um LegacyString ou LegacyNumber que implementa o comportamento das variáveis legadas. Uma sequência de instruções se transforma em uma sequência de chamadas de método que implementam o comportamento das instruções originais. De verdade, não há mágica neste processo. Há um trabalho árduo no desenvolvimento e muitos testes na infraestrutura que fazem essa nada-de-mágica.
Existe um espectro bastante amplo sobre como a conversão de linguagens pode ser feita. Um exemplo extremo é quando o código se parece quase como o código legado e os desenvolvedores de Java dizem: hein?! Um outro exemplo extremo é quando o código não se parece em nada como o legado original e os desenvolvedores de legados dizem: hein?! Esse “hein” se traduz em um índice de qualidade – e pronto! O que é que você – os seus desenvolvedores – precisa exatamente? Quem é que irá manter o seu código: desenvolvedores de Cobol retreinados ou caras de Java sensibilizados para o legado?
Com o rewriting, o código é ‘tão java’ quanto possível, porém, o conhecimento das últimas décadas dos desenvolvedores de legados será provavalmente descartado.
Os cross-compilers criam código que é executado em uma JVM e dificilmente se assemelha a (linguagem de) java. Eles também podem ter limitações de funcionalidade. (Não on-line?)
Podemos ajustar os recursos de conversão de acordo com os requisitos do cliente ao longo desse aspeto que eu mencionei para atingir um nível de qualidade de código que o seu pessoal acredita ser o melhor para a causa. Não existe uma conversão de abordagem única (one-size-fits-all). Além disso, podemos adicionar componentes específicos do cliente que fazem os desenvolvedores se inclinarem para a nossa solução.
Legibilidade
Nomes funky no código legado? Abreviações em nomes de variáveis e rótulos? Não tem problema. O nosso mecanismo de conversão vai descobrir o que o tio Jack quis dizer há 30 anos… Não, de verdade não vai.
Há muitos aspetos de legibilidade, nomear as convenções é um deles. Você receberá a obscuridade de volta após a conversão. É capaz que a conversão só vai piorar as coisas.
O código legado de espaguete é convertido em strings de fusilli quando o mecanismo de conversão tenta entender o fluxo de código. Não necessariamente se torna mais legível, mas pelo menos se torna de OO.
SonarQube
Estamos orgulhosos de fornecer código compatível com SonarQube – o mais alto nível. Mas! Há um ‘mas’ aqui, porque sempre há um ‘mas’. O código convertido corresponde ao legado. Nomes muito longos, nomes muito curtos, complexidade ciclomática, repetições de código, blocos de código vazios, blocos de código muito grandes e muitos outros são problemas que herdamos.
Acontece que modificamos nosso mecanismo de conversão para reduzir o número de problemas relatados pela SQ após consultar o cliente sobre os motivos e modificações possíveis para melhorar a qualidade.