Escolha uma Página

Para desenvolver qualquer produto, é necessário estar constantemente nomeando – concorda? Temos que criar nomes para variáveis, funções, argumentos, classes, etc.


Neste artigo, vamos falar sobre a importância de criar bons nomes e como eles influenciam positivamente no seu código. Vamos lá?

Utilizando nomes significativos

Primeiramente devemos ter em mente o quão importante é nomear no desenvolvimento de software.
Bons nomes podem economizar muito tempo na leitura do seu código, e é por isso que você pode gastar, sem problemas, um tempinho a mais para garantir que está nomeando da melhor maneira possível. Vamos ver um exemplo?

```java
List<int[]> lista = new ArrayList<>();
...
public List<int[]> obtem() {
    List<int[]> tmp = new ArrayList<>();
    for (int[] x : lista)
        if (x[0] == 4) tmp.add(x);
    return tmp;
}
```

O código acima não é complexo, é pequeno. Mas ainda assim, temos dificuldade em dizer o que ele está fazendo. O que é *lista* e o que estamos armazenando nela? Qual é a importância do primeiro elemento, zero, de um item da *lista*? O que significa o valor *4*? Como posso usar a *List<int[]>* que está sendo retornada?

É muito difícil responder essas perguntas sem conhecimento prévio do ambiente em que o código está inserido, e isso é um problema, pois em times ágeis e multidisciplinares, qualquer desenvolvedor deve entender claramente o seu código, não importa se é novo ou antigo em um projeto. Concorda? Vamos ver esse mesmo código melhorado:

```java
private final int STATUS = 0;
private final int STATUS_MARCADA = 4;
...
List<int[]> tabuleiroDoJogo = new ArrayList<>();
...
public List<int[]> obtemPecasMarcadas() {
    List<int[]> pecasMarcadas = new ArrayList<>();
    for (int[] peca : tabuleiroDoJogo)
        if (peca[STATUS] == STATUS_MARCADA)
            pecasMarcadas.add(peca);
    return pecasMarcadas;
}
```

Este código não está limpo, mas elimina quase tudo o que antes estava implícito. Com isso é fácil enxergar que o problema não está na complexidade de um código, e sim na quantidade de coisas implícitas. Quanto mais coisas implícitas seu código possui, mais difícil é a sua leitura; seja para qualquer outro desenvolvedor, ou para você mesmo, o próprio autor, um tempo depois.

Podemos falar sobre código limpo com mais detalhes ao longo de outros artigos, mas para começarmos a desenvolver um olhar crítico sobre o nosso próprio código, segue um exemplo de código limpo:

```java
...
List<Peca> tabuleiroDoJogo = new ArrayList<>();
...
public List<Peca> obtemPecasMarcadas() {
    List<Peca> pecasMarcadas = new ArrayList<>();

    for (Peca peca : tabuleiroDoJogo)
        if (peca.estaMarcada())
            pecasMarcadas.add(peca);
    return pecasMarcadas;
}
```

Evite confusões

Como desenvolvedores, não queremos dar falsas pistas sobre o entendimento do nosso código, certo? Alguns nomes de variáveis podem mascarar ou até indicar uma ideia diferente da rotina escrita para outro desenvolvedor que está lendo. Por exemplo:

```java
...
private String rm, cd, ls;
private int nulo = -1;
...
```

As variáveis *rm*, *cd* e *ls* têm nomes de comandos Unix amplamente usados. Entretanto, para o código desenvolvido, são nomes curtos e sem significado algum. A tendência é que, por isso, o desenvolvedor que está lendo associe automaticamente o propósito dessas variáveis no código com a funcionalidade desses comandos conhecidos.

O caso da variável *nulo* é simplesmente visual. As palavras *nulo* e *null* são muito parecidas, diferenciadas apenas pela sua última letra. Constantemente, quando estamos lendo, não lemos uma palavra inteira e a proximidade entre o nome da variável e a palavra protegida *null* pode causar desentendimento

Para enfatizar que não lemos uma palavra letra por letra, vamos observar o exemplo abaixo:

```java
class PROConversorDeObjetoSeralizadoEmXmlParaString { ... }
...
class PROConversorDeObjetoSeralizadoEmJsonParaString { ... }
```

Os nomes das duas classes acima são muito parecidos e difíceis de diferenciar até em uma leitura simples como no exemplo. Imagine o quanto piora em um código real?

Existem casos que levam os desenvolvedores a entender de outra forma o funcionamento de certas variáveis por causa da nomenclatura utilizada. No exemplo abaixo, a variável *nomesList* pode sugerir um comportamento diferente da sua declaração.

```java
...
private String[] nomesList;
...
```

Ao ler a palavra *List* em *nomesList*, imediatamente associamos essa variável a alguma implementação da interface List. O ideal é não utilizar tipos ao nomear uma variável, a não ser que seja bem necessário e útil, como é o caso das instâncias de *View* no desenvolvimento mobile. Nesse caso, utilizar simplesmente *nomes* seria bom; melhor ainda seria algo mais explícito, como: *nomesDosAlunos*.

Diferenças significativas

Vamos começar com um exemplo simples: uma função que copia dois vetores de char:

```java
public static void copia(char[] c1, char[] c2) {
    ...
}
```

Nossa primeira dúvida ao olhar essa função é saber quem é o vetor base e quem é o destino da função. Em seguida, tentamos fazer atribuições sem ter certeza, pensando que o padrão foi seguido e o primeiro argumento é a base e o segundo é o destino. O último passo é assumir a insegurança e parar o fluxo do nosso trabalho só para testar o comportamento dessa função.

```java
public static void copiaChars(char[] base, char[] destino) {
    ...
}
```

Com a função escrita desta maneira, com certeza não perderíamos tempo questionando o comportamento da função e, muito menos, pararíamos nosso fluxo de trabalho para realizar testes que não agregam valor ao nosso sistema.

É comum que determinadas funções tenham comportamento semelhante no nosso código. Sempre que isso acontecer, devemos ter o trabalho de indicar aos outros desenvolvedores a utilização certa e a diferença entre essas rotinas.

```java
obtemContas();
obtemContasAtivas();
obtemContaAtiva();
obtemInfoDeContaAtiva();
```

O fato dos escopos das funções estarem reduzidos e os retornos omitidos não possuírem uma relevância tão significativa. O que realmente importa, é que embora tenhamos nomes diferentes nas quatro funções, não temos de fato uma diferença de sentido entre elas. É como nomear duas classes, uma chamada *ContaInfo* e outra *ContaDado*; ambas possuem nomes diferentes; mas qual é a diferença prática?

Caso você não tenha se convencido ainda por causa da falta de retorno das funções, deve lembrar que no meio do código não teremos sempre o escopo disponível, e teríamos que consultar sua declaração toda hora. Mesmo que as IDEs ajudem nessa consulta, é improdutivo ter que fazer isso várias vezes ao longo do desenvolvimento, principalmente se a definição real está em outra camada do sistema.

Seja consistente

É importante escolher um padrão para o nosso código e permanecer com ele ao longo de todo o projeto. É prejudicial para o entendimento do nosso código utilizar diferentes nomenclaturas para ações semelhantes. Por exemplo:

```java
public String getNome() { ... }

public String recebeNome() { ... }

public String obtemNome() { ... }
```

Qual é a diferença entre os três métodos acima? O método *getNome()* pode fazer parte dos *getters e setters* da classe, mas e o *recebeNome()* e *obtemNome()*? Qual é a diferença entre esses dois? Pior, pode ser que eles não tenham diferença alguma na sua funcionalidade. Seria melhor estabelecermos um padrão e utilizarmos consistentemente no nosso código.

Caso exista diferença entre os três métodos, podemos separá-los por classes e sempre utilizar a nomenclatura *get*.

Nosso padrão também deve ser aplicado às classes que criamos.

```java
public class ProtocoloController { ... }

public class DispositivoManager { ... }
```

*Manager* e *Controller* são duas palavras genéricas no meio de desenvolvimento de sistemas. Nem sempre é trivial explicar o que um dos dois faz, e ter esses dois nomes juntos pode complicar ainda mais, fazendo surgir dúvidas como: “O que faz um Controller e um Manager?” ou “Por que as duas classes não são um Controller ou um Manager?”.