Dicas de Boas Práticas de Codificação

Este post não traz nenhuma novidade para quem já desenvolve há algum tempo, e a intenção é atingir aqueles que estão começando a programar em Java.

Resolvi juntar algumas dicas de padrões de codificação e melhores práticas para códigos a serem aplicados no desenvolvimento de aplicações Java.

São abordados padrões de nomes de arquivos, organização de código, endentação, comentários, declarações, sentenças, espaços em branco, convenção de nomes, práticas de programação e exemplos de código.

Estes padrões são baseados em princípios de engenharia de software que produzem códigos fáceis de entender, fáceis de manter e escaláveis. As convenções aqui adotadas foram fortemente baseadas no documento de Convenção de Codificação para a Linguagem de Programação Java, da Sun Microsystems.

Algumas constatações reforçam a necessidade de se adotar uma padronização durante do desenvolvimento:

  • 80% dos custos de um software é referente à manutenção.
  • Dificilmente qualquer software é mantido durante toda sua vida útil pelo autor original.
  • Convenções de código aumentam a legibilidade do software, permitindo que os desenvolvedores entendam novos códigos mais rapidamente e completamente.

No desenvolvimento de sistemas o uso de padrões de codificação promove o aumento da consistência do código e da produtividade da equipe. A seguir são descritas as principais instruções para a codificação de um código Java com padronizado e com qualidade.

Convenção de Nomes

Mantenha o tamanho dos nomes grande o bastante para transmitir o que eles representam. Exemplo: primeiroNome, sobrenome, ordemServico, etc.

Nomes de Classes e Interfaces

Os nomes de classe devem ser substantivos e, em caso de nomes compostos, utilize nomes com a primeira letra de cada palavra interna maiúscula. Use palavras inteiras evitando acrônimos e abreviaturas. Exemplo: Cliente ou ContaCliente.

Nomes de Métodos

Os nomes dos métodos devem ser verbos, em casos compostos com o primeiro nome minúsculo, e com a primeira letra de cada palavra interna em maiúsculo. Exemplo:

calcularPagamento().

Nomes de Variáveis

Os nomes de variáveis devem estar com uma primeira letra minúscula e, em caso de nomes compostos, com a primeira letra de cada palavra interna em maiúsculo. Exemplo: contraPeso, primeiroNome, etc.

Use abreviações consistentemente. Exemplo: numPedido, numChamado. Neste caso, num representa Numero.
Evite os nomes que são similares. Exemplo: o numCliente e numcliente.

Use nomes no plural para representar coleções tais como uma disposição ou um vetor. Exemplo: CustomerPK[] clientes ou Vector politicasDeAcesso.

Nomes de Constantes

Os nomes de constantes para tipos de dados ordinais devem ter todas as letras em maiúsculo, separadas por underscore. Exemplo:

public static final int MAX_POLICY_AMOUNT; ou
public static final char PROCESS_INFO_COMMAND;

Documente com Comentários

Adicione comentários para facilitar a compreensão do código. Mantenha o comentário simples e separe-os de tal forma o código fique limpo e legível. Escreva também os comentários onde alguma explanação é necessária. Não escreva comentários para as coisas óbvias. Forneça documentação de acordo com a especificação do javadoc, tal que os arquivos do Java código podem ser usados para produzir a documentação externa das classes.

Documentação de Classes

Para documentar classes forneça comentários imediatamente antes de sua definição, especificando a finalidade e histórico de desenvolvimento.

Documentação de Interfaces

Para documentar interfaces especifique a finalidade nos comentários da documentação, imediatamente antes de sua definição. Para cada método siga os padrões da documentação de métodos de membro.

Documentação de Pacotes

Forneça documentação que especifique o relacionamento de um pacote com suas classes e Interfaces.

Use Linhas em Branco

Forneça linhas em branco entre as seções do código para melhorar a legibilidade. Use uma linha em branco nas seguintes circunstâncias:

  • Para separar as definições de classes das definições de métodos;
  • Para separar as variáveis locais de um método;
  • Para separar blocos de código; e
  • Para separar comentários das seções lógicas do código.

Espaços em Branco e Tabulação

Use o espaço em branco para melhorar a legibilidade do código nas seguintes circunstâncias: Entre uma palavra-chave e um parêntese. Exemplo:

while (condicao) {
}

Após vírgulas na lista entre parênteses. Exemplo:


operacao(param1, param2, param3);

Entre um operador binário e seu operando. Exemplos:


x += y + z;
a = (a + b) / (c * d);

Entre expressões em uma declaração “for”. Exemplo:


for (expr1; expr2; expr3)

Na utilização de casts.


umMetodo((byte) num, (Object) x);

Variáveis Locais

Declare uma variável local por linha do código e adicione um comentário que identifique a variável. Exemplo:

int contador = 0; // contador para número de referências

Declare todas as variáveis locais no começo dos blocos. Isto facilitará a localização das definições variáveis pelo programador. Exemplo:


private void calcularProcessosPendentes() {
boolean processoEncerrado = false; // indica término do processamento
}

Use cada variável local para uma finalidade específica.
Inicialize todas as variáveis locais onde elas são declaradas. A única razão para não inicializar uma variável no local onde ela é declarada é quando o valor inicial da variável depende de um processamento que ocorrerá posteriormente.


int contador = 0; // contador para número de referências
int maxReferencias; // o número máximo de referências a serem processadas
…
maxReferencias = getMaxRefencias(…, …);

Evite as declarações locais que sobreponham declarações em níveis superiores. Exemplo:


int contador = 0; //…
…
metodo() {
    if (condicao) {
        int contador = 0;
        …
    }
    …
}

Atributos de Membro

Para declarar atributos de membro utilize os seguintes padrões:

Finalidade: Documente a finalidade do atributo;
Visibilidade: Mantenha a visibilidade tão baixo quanto possível;
Iniciação: Certifique-se de que todos os atributos estão inicializados antes que sejam alcançados. Inicialize todos os atributos no momento da criação do objeto. A inicialização posterior pode ser usada para os campos que não são acessados regularmente.

Métodos de Membro

Para declarar métodos de membro utilize os seguintes padrões:

Nomenclatura: use get/set como um prefixo do nome do campo para todos os métodos de ascensão, a menos que forem do tipo booleano. Use o prefixo “is” para nomes de métodos que referenciem campos booleanos. Utilize também a primeira palavra do nome do método de membro como um verbo forte, ativo. Exemplo:


getPotenciaMotor(), setPotenciaMotor(), isAutomatico(), reduzirMarcha().

Visibilidade: Mantenha a visibilidade de funções de membro tão restritiva quanto possível para minimizar o acoplamento entre as classes;
Documentação: Inclua um cabeçalho para especificar as seguintes informações da função de membro:

  • O propósito da função;
  • Seu valor de retorno;
  • Os parâmetros;
  • As mudanças nas versões do código.

Parâmetros

Evite nomear parâmetros com o mesmo nome que as variáveis de membro. Isto evitará referenciar cada variável de membro utilizando o operador “this”, dificultando a localização de erros. Documente os parâmetros de uma função de membro no header usando a tag @param do javadoc. A documentação deve ser obrigatória para descrever todas as limitações ou pré-condições.

Declarações ou Comandos

Cada linha deve conter no máximo um comando. Exemplo:

contador++; x = y; // EVITE ISSO!

Chaves ou Blocos

Siga um esquema consistente para a abertura e fechamento de chaves. Alinhe a abertura e fechamento das chaves verticalmente. Isto facilitará a identificação do começo e término dos blocos. Exemplo:

class Cliente
{
    public void operacaoParaCliente()
    {
        if(condicao)
        {
        }
    }
}

Alternativamente, ponha a chave da abertura na extremidade da linha que começa o bloco. A chave de fechamento deve começar uma nova linha e ser posicionada no começo do comando de bloco. Exemplo:


class Cliente {
    public void operacaoParaCliente() {
        if(condicao) {
        }
    }
}

Ordem dos Membros

Declare membros de acordo com a ordem de visibilidade, do mais visível para menos visível, conforme modelo abaixo:

construtores (constructors)
public member functions
protected member functions
private member functions

Minimize a utilização do modificador de acessos public e protected. Isto reduz o acoplamento e deixa o código mais compreensível. Evite usar nomes de objetos para acessar membros estáticos (static members), em vez disto, use o nome da classe preferivelmente.

Concatenação de Strings

Evite realizar a concatenação de Strings com o operador “+“. Strings são objetos imutáveis, e por esta razão, a cada vez que uma concatenação é realizada, novos objetos são criados na memória:

String a = “Evite“;
a = a + “realizar a concatenação“;
a = a + “de Strings assim!“;

Para concatenação, procure utilizar as classes StringBuilder ou StringBuffer:


StringBuilder a = new StringBuilder(“Procure“);
a.append(“realizar a concatenação“);
a.append(“de Strings assim!“);

Cuidados na Manipulação de Objetos que Podem Estar Nulos

Ao realizar a chamada de métodos em objetos que poderiam estar nulos, tenha sempre o cuidado de testá-lo antes, a menos que tenha a certeza de que o objeto não estará nulo.
Um exemplo útil, no caso de comparação de Strings:

Ao invés de realizar a comparação desta maneira:


if(umaString.equals(““)){
…

Faça o seguinte, chamando o método equals no valor literal:


if(““.equals(umaString)){
...

Remover Imports Desnecessários

É importante, por uma questão de economia de memória, manter nas classes e interfaces somente as definições de imports que são utilizadas.
Uma outra prática importante, que já é reforçada pelas IDE’s, é fazer o import classe a classe, ao invés de importar todos as classes de um determinado pacote.

Utilize Parênteses Sempre que Puder

Não economize na utilização de parênteses quando estes puderem deixar uma expressão mais clara.

Atribuição de Variáveis

Evite fazer múltiplas atribuições a uma mesma variável em uma única linha:

fooBar.fChar = barFoo.lchar = 'c'; // EVITE ISSO!

Referência a Atributos e Métodos Estáticos

Sempre referencie membros estáticos (atributos e métodos) através da classe, e não de uma instância da mesma:


UmaClasse.metodoEstatico(); // OK
instanciaDeUmaClasse.metodoEstatico(); // EVITE ISSO!

Utilize Chaves Sempre!

Sempre utilize chaves para delimitar blocos de comandos, mesmo que estes tenham apenas uma instrução:

if(determinadaCondicao) // EVITE ISSO!
    realizaOperacao();

if(determinadaCondicao){ // OK
    realizaOperacao();
}

Bom, definitivamente não há nada de novo aqui para quem já desenvolve há algum tempo, com uma ou outra adaptação.

O importante é definir quais práticas se adequam à sua realidade/equipe/projeto e seguí-la.

Está dada a dica!

Referência

http://www.oracle.com/technetwork/java/codeconv-138413.html

Um comentário sobre “Dicas de Boas Práticas de Codificação

  1. Olá, Luiz,

    tudo bem?

    Gostei muito do conteúdo do seu blog e por isso gostaria de te fazer um convite.

    Caso tenha interesse, basta entrar em contato.

    Obrigado!

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s