Opinem: Qual código a seguir é mais claro? [2]

16 respostas
F

Olá, pessoal,
Lá venho eu novamente intimar-vos. :smiley:

Tenho dois métodos super-simples, que fazem a mesma coisa. A pergunta é a mesma: qual o código é mais claro? Eu considero o segundo mais claro.

public static boolean numero(int i) {
        if (i == 1) {
            return true;
        }
        if (i == 2) {
            return true;
        }
        return false;
    }

    public static boolean numero1(int i) {
        if (i == 1) {
            return true;
        } else if (i == 2) {
            return true;
        } else {
            return false;
        }
    }

O return, além de proporcionar o retorno de um valor, também serve para parar (break) a execução de um método. No primeiro, se i==1, o método retorna true e o outro if (i==2), não será sequer executado (uma vez que um retorno já foi feito). Assim sendo, caso isso ocorra, o return false da última linha (que está fora de qualquer condição, e, portanto, deveria ser executado) não é lido. Por isso, no primeiro caso, não há necessidade de else, já que apenas um if será lido.
Entretanto, o segundo método é mais claro, já que a estrutura é mais elaborada e fácil de entender (mesmo por quem não saiba como de fato funciona o return).

E aí? O que vocês acham?

16 Respostas

romarcio

Também poderia ser assim:

public static boolean numero1(int i) {
        if (i == 1 || i == 2) {
            return true;
        } else {
            return false;
        }
    }

    public static boolean numero1(int i) {
        if (i == 1 || i == 2) {
            return true;
        }
        return false;
    }	

    public static boolean numero1(int i) {
        return i == 1 || i == 2 ? true : false;
    }
ViniGodoy

Eu ainda prefiro esse:

public static boolean numero1(int i) { return i == 1 || i == 2; }

Mas sobre a pergunta original do tópico. Com esses nomes de variável, nenhum dos dois códigos é claro.

Acho o primeiro menos pior.
Ele deixa claro que o if irá abandonar o método.
Também evita identação, e elses inúteis.

Finalmente, o código deixa claro que aquele return false ali é uma condição final.

O return dentro do else não deixa isso claro. Você tem que analisar todas as condições do if para perceber que todas tem um return dentro, e que um código após esse if jamais seria executado.

Além disso, se um programador não souber o significado de um return, é melhor ele nem estar programando.

romarcio

ViniGodoy:
Eu ainda prefiro esse:

public static boolean numero1(int i) { return i == 1 || i == 2; }

Mas sobre a pergunta original do tópico. Com esses nomes de variável, nenhum dos dois códigos é claro.

Acho o primeiro menos pior.
Ele deixa claro que o if irá abandonar o método.
Também evita identação, e elses inúteis.

Finalmente, o código deixa claro que aquele return false ali é uma condição final.

O return dentro do else não deixa isso claro. Você tem que analisar todas as condições do if para perceber que todas tem um return dentro, e que um código após esse if jamais seria executado.

Além disso, se um programador não souber o significado de um return, é melhor ele nem estar programando.

Puxa, é mesmo Vini. Ficou mais simples ainda.
Não tinha pensado nesse modo.

InicianteJavaHenriqu

Olá felipe_fernandes :smiley:

Mas se daqui alguns dias ou daqui algum tempo, vc tiver que verificar na sua função 5 ou + números :?:

Eu prefiro assim:

public static boolean numero_1(int i) {
        boolean retorno = true;
        switch (i) {
            case 1:
                return retorno;
            case 2:
                return retorno;
            case 3:
                return retorno;
            case 4:
                return retorno;
            case 5:
                return retorno;
            default:
                return !retorno;
        }
    }

flw :thumbup:

pmlm

Para que complicar?

public static boolean numero_1(int i) {
    return i > 0 && i < 6;
}
ViniGodoy

Pensei a mesma coisa. Sem falar que switch geralmente cheira mal.

InicianteJavaHenriqu

Legal :smiley: bem simples.

Vamos pensar também que nunca iremos precisar disto:

public static boolean numero_1(int i) {  
        boolean retorno = true;  
        switch (i) {  
            case 1:  
                System.println(i + " é ímpar");
                return retorno;  
            case 2:  
                System.println(i + " é par");
                return retorno;  
            case 3:  
                System.println(i + " é ímpar");
                return retorno;  
            case 4:  
                System.println(i + " é par");
                return retorno;  
            case 5:  
                System.println(i + " é ímpar");
                return retorno;  
            default:  
                System.println("Este número não é válido!");
                return !retorno;  
        }  
    }

:shock: Por quê?

ViniGodoy

:shock: Por quê?

Geralmente switchs podem ser substituídos por maps, tabelas ou polimorfismo.
Quando usados para tratar enums, eles tendem a se espalhar pelo código, gerando duplicação e tornando a implementação de mais um item do enum confusa.

InicianteJavaHenriqu

:shock: Por quê?

Geralmente switchs podem ser substituídos por maps, tabelas ou polimorfismo.
Quando usados para tratar enums, eles tendem a se espalhar pelo código, gerando duplicação e tornando a implementação de mais um item do enum confusa.

Interessante, não sabia disto :smiley:

Mas, no caso do código inicial do tópico daria para ser substituídos por maps, tabelas ou polimorfismo :?:

Talvez até não seria necessário, pois a maneira "mais prática e simples, porém não muito reutilizável" foram estas:

return i == 1 || i == 2;
return i > 0 && i < 6;

flw :thumbup:

ViniGodoy

Evidente que sim. Você pode ter um Set que representa os valores que são true:

Set<Integer> valores = new HashSet<Integer>(); valores.add(1); valores.add(2);

E no método só fazer:

public static boolean numero1(int i) { return valores.contains(i); }

Se o tipo de retorno fosse mais complexo que um boolean, a tabela poderia ser um Map<Integer, TipoDeRetorno>.

No caso do polimorfismo, esse código em particular não faz muito sentido.

ViniGodoy

O que você quer dizer com “porém não muito reutilizável”? Creio que nenhuma das soluções foi reutilizável.

InicianteJavaHenriqu

O que você quer dizer com “porém não muito reutilizável”? Creio que nenhuma das soluções foi reutilizável.

Quis dizer que: caso daqui alguém tempo fosse necessário exibir tbm se o número é par, ímpar ou inválido, meu switch cheirando mal poderia fazer isto.

Mas, a maneira certa seria mesmo criar outra solução para isto.

InicianteJavaHenriqu

Então agora…

…só basta ao felipe_fernandes escolher à maneira deseja para responder a pergunta inicial:

Tenho dois métodos super-simples, que fazem a mesma coisa. A pergunta é a mesma: qual o código é mais claro?

Já vimos aqui maneiras:

[list]simples[/list]
[list]super simples[/list]
[list]complicadas e cheirando mal[/list]
[list]sem sentido[/list]
[list]Orientadas a Objeto[/list]

ViniGodoy

Claro, se o problema era exibir quem era par ou impar nos números menores que 5, o ideal é fazer assim:

public static boolean numero_1(int i) { if (i &lt; 1 || i &gt; 5) { System.out.println(&quot;Este número não é válido!&quot;); return false; } String tipo = i % 2 == 0 ? &quot;par&quot; : &quot;ímpar&quot;; System.out.printf(&quot;%d é %s.%n&quot;, i, tipo); return true; }

InicianteJavaHenriqu

Tudo bem ViniGodoy

Como eu já disse: tem diversas maneiras para o felipe_fernandes resolver o problema inicial.

Não vou fica aqui enchendo meu contador de mensagens à toa. Para que daqui alguns anos eu olhe para trás e pense: “Tenho mais de 19500 mensagens, mas 19000 eu consegui com discussões fúteis, como está…

flw sem ressentimentos.

ViniGodoy

Ei, desculpe, não sabia que havia te ofendido, nem que estava achando a discussão inútil.
Eu, particularmente, acho esse tema bem interessante, falamos sobre coleções, polimorfismo, refatoração, sintomas de mau código.
Não vejo porque a discussão tenha sido fútil.

Sobre o lance de cheirar mal, eu não tinha a intenção de ser ofensivo.
Esse é o termo usado no livro refatoração, do Martin Fowler.
E o switch é um dos elementos descritos como “mau cheiro” nesse livro.

Criado 11 de fevereiro de 2012
Ultima resposta 12 de fev. de 2012
Respostas 16
Participantes 5