Tableless

Busca Menu

Código Limpo

Seja o primeiro a comentar por

Um dos assuntos que costumo discutir bastante com a galera é sobre qualidade de código. Nesses papos sempre vem questões como: quais práticas podemos adotar para ter um código de alta qualidade? E como sabemos se o nosso código está bom? Como temos certeza de que estamos no caminho certo?

Vou explicar meu humilde ponto de vista com exemplos e opiniões sobre qualidade de código. Vou abordar casos de uso com JavaScript, mas nada te impede aplicar muitas dessas dicas usando outras linguagens.

GDD – Gambiarra Driven Development

Vamos começar pela metodologia mais antiga e talvez a mais adotada no mercado. Já trabalhei com profissionais que defendiam com unhas e dentes o não uso de padrões e boas práticas. Vamos ver as desculpas justificativas mais usadas:

  1. O projeto é muito simples. Não precisa de muita frescura.
  2. Faço isso há muitos anos e dificilmente tenho problemas.
  3. Desse jeito entrego em 10 minutos o que faríamos em horas.
  4. Não preciso padronizar, o código tá fácil de entender.
  5. Não temos tempo para documentar.
  6. Não temos tempo para escrever testes.
  7. Não temos tempo para refatorar.
  8. Esse código aí não é meu.

Conseguiu se lembrar de alguns momentos na sua carreira, onde você já falou ou ouviu qualquer uma das frases acima? Não? Sortudo!

Não acredito que é errado você usar uma gambiarra para resolver um erro, desde que posteriormente você empregue uma solução mais robusta. O problema maior ocorre quando o uso de soluções paliativas se tornam frequentes.

Mas de longe esse é o único ou pior problema que encontramos na codificação. Gambiarras e anti-patterns podem ser bons e eficientes a curto prazo, mas a longo prazo te mostram o inferno na terra.

Vou apontar algumas boas práticas voltadas á escrita de código e o motivo para usá-las.

Antes de tudo…

Você como desenvolvedor, tem a obrigação de entender cada linha de código que você escreve.

Estude boas práticas e metodologias sempre. Mas não seja ingênuo a ponto de acreditar que a adoção de uma delas irá salvar parte do seu projeto/equipe. Muitas soluções podem trazer novos problemas. Quantas vezes a solução de um bug gerou outros 10 na aplicação? Por isso é necessário sempre ter na equipe alguém experiente com bastante vivência, que saiba direcionar o projeto nesses cenários.

Já vi projetos que começaram repletos de boas práticas, e terminaram desastrados por conta da falta de maturidade prática da equipe. O ponto inicial que jamais deve ser ignorado é: você como desenvolvedor, tem a obrigação de entender cada linha de código que você escreve.

No caminho certo

Seu código atual tem uma qualidade superior comparado com o que você escreveu há 6 meses atrás? Se sua resposta for sim, isso indica que você está no caminho certo. Programação é algo em constante evolução, o você programador, também deve evoluir. Com o passar dos anos seu código deve se tornar mais bem organizado, limpo e elegante.

Uma leitura obrigatória é o livro Clean Code. Muitos artigos e palestras sobre boas práticas (incluindo esse artigo), repetem pontos abordados nesse livro. Já vi até empresas cobrando a leitura desse livro como requisito para contratação.

Código Limpo

Enquanto o GDD pode te dar felicidade a curto prazo, escrever código de forma limpa e consistente vai te garantir um futuro mais confortável. Você terá um código de fácil entendimento, o que tornará sua manutenção mais eficiente. E se você for um garoto prendado e cobrir sua aplicação com o máximo possível de testes, erros de regressão não irão mais chatear teu cliente/chefe.

Vou focar em poucos pontos. Se quiser mais conteúdo, leia o Clean Code.

Code Review

Sempre peça para um colega revisar teu código. Se outra pessoa entendeu perfeitamente o que você escreveu, é um bom sinal.

“Qualquer tolo consegue escrever código que um computador entenda. Bons programadores escrevem código que humanos possam entender.” – Martin Fowler

Linters

Ferramentas que escaneiam nosso código procurando o uso de más práticas e possíveis erros de execução, são nossos aliados. No dia-a-dia costumo usar o JSHint e agora meu novo parceiro: JSInspect.

Gosto do JSHint pelo fato de poder customizar algumas regras. Já o JSInspect te ajuda á identificar o padrão copy & paste, te ajudando a escrever módulos melhores.

Nomenclaturas

Quando me perguntam qual parte da programação eu acho mais difícil, respondo na lata: nomear coisas.

Passamos boa parte do tempo fazendo isso no nosso código, nomeando funções, variáveis, classes, namespaces, etc. Muitas vezes demoramos até chegar em um resultado bacana.

Seja verboso

“Existem duas coisas muito difíceis na Ciência da Computação: invalidar cache e dar nome às coisas.” – Phil Karlton

Consegue me dizer se você entende de cara o que faz a instrução abaixo?

u.cptTasks = false;

E agora com o código abaixo?

var u = new User();
u.name = 'Joana Souza';
u.adminPerm = true;
u.cptTasks = false;
u.save();

Conseguiu entender tudo? Vamos ver se fica mais fácil:

var user = new User();
user.name = 'Joana Souza';
user.hasAdministratorPermissions = true;
user.didCompleteAllTasks = false;
user.save();

Nomear a variável como u não ajudou muito. Principalmente se você for reutilizar essa variável muitas linhas abaixo. Abreviações também atrapalham bastante. Duvido que de imediato você soube o significado de u.cptTasks. Pode ter tido várias idéias, o que te guiou ao velho achismo. E quantos erros já não cometemos pelo simples fato de acharmos isso ou aquilo?

Considere o uso da nossa querida Língua Portuguesa

Usar a língua portuguesa para nomear coisas pode ser muito bom, principalmente para os novatos. Pelo simples motivo de que fazendo isso, fica mais visível o que é API nativa da linguagem/browser, e API proprietária. Dá uma olhada:

var usuario = new Usuario();
usuario.nome = 'Joana Souza';
usuario.temPermissoesAdministrativas = true;
usuario.completouTodasTarefas = false;
usuario.salvar();

Ficou mais confortável né? Seu cérebro praticamente se deu ao único trabalho de compreender o código. Não precisou traduzir de um idioma para outro. Mas isso é também uma faca de dois gumes.

Conhecer a língua inglesa é extremamente importante no mundo da programação, pois muitas documentações e materiais estão nesse idioma. Logo, nomear coisas em português te tira a oportunidade de praticar o idioma, pelo menos na forma escrita. Vale á pena bater um papo com a sua equipe á respeito disso.

Adote uma convenção

A adoção de uma convenção facilita muito na padronização de estilo de escrita e organização de código. É uma ótima opção iniciar com alguma existente:

Bônus:

Variáveis e funções não utilizadas

Variáveis e funções não utilizadas são um belo exemplo de sujeira. Alguma vez você já deu manutenção em algum código, cujo algum tempo foi investido para compreender o que foi escrito, pra no final das contas perceber que o código estava morto, sem utilização? Chato, né?

Pra se livrar dessa sujeira é bem simples: ninguém está usando? Apague! Essa regra também vale para código comentado.

Reinvenção da roda

Esse erro é geralmente cometido por novos e antigos juniores (entendo como antigo júnior aquele profissional que programa há muitos anos, mas nunca se interessou em aprofundar em uma linguagem).

O fato de não conhecer muito bem a API da linguagem, pode te levar á reinventar á roda.

Um exemplo disso é quando precisamos fazer um filtro em um array. Quem não está familiarizado, irá primeiramente fazer o bom e velho for, possivelmente desconhecendo outras opções como Array.filter e Array.map.

Funções Pequenas

Funções devem ser claras, objetivas e pequenas. Respeite a regra da responsabilidade única: sua função deve fazer somente uma coisa, e deve fazê-la muito bem.

Dá uma olhada no exemplo abaixo:

usuario.salvar()

...

function salvar() {
    var camposObrigatorios = [ 'nome', 'email', 'cpf' ];

    camposObrigatorios.forEach( ( propriedade ) => {
        if ( !usuario[ propriedade ] ) {
            throw new Error( `É obrigatório informar o ${ propriedade } do usuário.` );
        }
    } );

    $http.post( 'http://app.com/api/usuario', usuario )
        .success( ... )
        .error( ... )
        .finally( ... );
}

Pelo nome da função ficou claro o objetivo dela. Mas analisando vemos a implementação de duas coisas: validação e persistência dos dados. Poderíamos dividir as responsabilidades da seguinte forma:

validarUsuario() && usuario.salvar();

...

function validarUsuario() {
    var camposObrigatorios = [ 'nome', 'email', 'cpf' ];

    camposObrigatorios.forEach( ( propriedade ) => {
        if ( !usuario[ propriedade ] ) {
            throw new Error( `É obrigatório informar o ${ propriedade } do usuário.` );
        }
    } );

    return true;
}

function salvar() {
    $http.post( 'http://app.com/api/usuario', usuario )
        .success( ... )
        .error( ... )
        .finally( ... );
}

Manter suas funções enxutas te auxilia á praticar o reuso do código.

Esse é um assunto que pode ser extenso. Uma discussão bem bacana rolou no StackOverflow. Dá uma olhada aqui.

Comentários

Já ouvi dizer que código semântico dispensa comentários. Concordo parcialmente com isso. Acredito que é válido usar comentários nas seguintes situações:

  • Utilização muito pouco comum de uma parte da API pode ajudar a galera mais nova
  • Nem sempre conseguimos deixar nosso código semântico, a ponto dele contar o que está acontecendo
  • Existem poucos momentos em que devemos fazer uso de uma má prática. E é bom deixar documentado o motivo antes que alguém refatore e quebre alguma funcionalidade
  • Sua aplicação expõe uma API pública. Sugiro o uso do JSDocs para manter um padrão.

Agora  /* código comentado */ é algo deve ter pouquíssima tolerância.

Indentação

Esse é conhecido como problema de perfumaria. Saca só:

if(usuario.idade!==null||usuario.idade!==undefined||typeof usuario.idade == 'number'||usuario.idade<18){
  alert('O usuário não possui idade suficiente para ser cadastrado nesse sistema.');
  return false;
}else{
    usuario.salvar();
}

Lindo né? Que tal dar mais espaço pra essa bagunça?

if ( usuario.idade && typeof usuario.idade === 'number' && usuario.idade < 18 ) {
    alert( 'O usuário não possui idade suficiente para ser cadastrado nesse sistema.' );
    return false;
}

usuario.salvar();

E agora? Ficou mais fácil de ler?

Enfiar todo o código em uma pequena lata de sardinha pode dificultar um pouco a sua compreensão, por mais que o seu editor de texto ou IDE tenha um highlight com alto contraste. Uma ferramenta bacana pra te ajudar á manter esse padrão é o JSCS. Gosto de usar o preset jQuery dessa ferramenta, pois o código fica com mais espaçamento, deixando o mais confortável para ler.

Vale lembrar que…

Muitas dicas dadas aqui retirei do livro Clean Code, e outras aprendi com o passar do tempo em experiência com diversos projetos. O seu comentário com um ponto de vista diferente pode me ajudar á aprender mais sobre o assunto.

Espero ter ajudado.

=)

Publicado no dia