Return dentro do if, é uma boa pratica de programação?

Pessoal, desculpa a pergunta besta, mas gostaria de saber se:

public boolean addWine(int row, int column, Wine wine) {
    if (validatePositions(row, column) && mat[row][column] != null) {
        mat[row][column] = wine;
        return true;
    }
    return false;
}

utilizar o return dessa forma dentro do if, é uma boa pratica de programação? ou o correto seria usar uma variável booleana como flag (sinalizador) e então retorna-la modificada pela condição? como:

    public boolean addWine(int row, int column, Wine wine) {
        boolean flag = false;
        if (validatePositions(row, column) && mat[row][column] != null) {
            mat[row][column] = wine;
            flag = true;
        }
        return flag;
    }

???

Eu acho a primeira opção mais legível.

Essa resposta também é interessante: https://stackoverflow.com/a/733858

Esquece um pouco essa história de “boa prática”. O que existe é “o que faz mais sentido” em cada caso.

No seu exemplo, não faz tanta diferença, a não ser que criou uma variável a mais que parece desnecessária, então eu escolheria a primeira opção, por ser mais sucinta.


Um detalhe importante é que o return não só retorna o valor, como também não executa mais nada dentro do método. Então faria diferença se tivesse mais coisas no meio. Ex:

public boolean addWine(int row, int column, Wine wine) {
    if (validatePositions(row, column) && mat[row][column] != null) {
        mat[row][column] = wine;
        return true;
    }

    // faz mais coisas aqui
    fazMaisCoisas();

    return false;
}

Nesse caso, se entrar no if, ele retorna e não executa o trecho que faz mais coisas (este trecho só executa se ele não entrar no if).

Agora se for assim:

public boolean addWine(int row, int column, Wine wine) {
    boolean flag = false;
    if (validatePositions(row, column) && mat[row][column] != null) {
        mat[row][column] = wine;
        flag = true;
    }

    // faz mais coisas aqui
    fazMaisCoisas();

    return flag;
}

Aí o trecho que faz mais coisas sempre é executado (independente de entrar ou não no if), já que o return só é feito no final.

Então você teria que ver se quer executar essas coisas a mais sempre, ou só em determinadas condições.

Claro que o trecho que faz mais coisas pode ter seu funcionamento mudado de acordo com o valor da flag, por exemplo, mas aí varia conforme o caso.

Enfim, eu gosto de retornar tão logo eu saiba que não é preciso executar mais nada. Tem gente que não. Mas tem que avaliar o todo pra saber se é pra retornar mesmo ou se ainda tem mais coisas pra fazer. Cada caso é um caso, não tem “a regra de ouro” (a tal da “boa prática”) pra isso.


Um exemplo “clássico”, verificar se determinado valor existe em um array:

// verifica se n existe no array
public boolean existe(int n, int[] valores) {
    for (int v: valores) {
        if (n == v) {
            return true; // encontrei
        }
    }
    return false;
}

Eu só quero ver se existe ou não, então se eu encontrar, já posso retornar true (não tem porque continuar procurando se já encontrei).

Agora se fizer com flag:

// verifica se n existe no array
public boolean existe(int n, int[] valores) {
    boolean achou = false;
    for (int v: valores) {
        if (n == v) {
            achou = true; // encontrei
        }
    }
    return achou;
}

Mesmo depois de achar, ele continua procurando, até o final do array, o que é mais ineficiente (pra não dizer “burro” - se já achou, pra que continuar procurando, se eu só quero saber se existe ou não?)

Mas claro que é só um exemplo. Como eu já disse, cada caso é um caso…

3 curtidas

Muito obrigado pelo esclarecimento, essa duvida surgiu porque um professor em um momento da aula disse que não é uma boa pratica interromper a execução do bloco de código usando o return, fiquei tipo… aan?, Enfim, Obrigado pela resposta completíssima!

Eu prefiro não criticar o professor sem conhecê-lo, então diria que depende.

Se ele disse que isso é ruim sempre, em todos os casos, para qualquer situação e/ou contexto, então eu questionaria. Mas se foi citado um contexto específico, aí tem que analisar qual foi esse contexto. Como eu disse, varia muito, tem casos em que será melhor ou pior, tem casos que será “obrigatório” usar ou não usar (pois a forma como foi feito o algoritmo pode depender disso), etc etc etc.

No exemplo acima, de verificar se um elemento existe no array, não há motivo para não interromper, então o return é perfeitamente adequado. Se já encontrei o que queria e não há mais nada a ser feito, pra que continuar procurando? Só para manter um suposto “purismo”? Claro que dá para fazer com o return só no final, e sem precisar percorrer todo o array depois que encontrou o elemento:

public boolean existe(int n, int[] valores) {
    boolean achou = false;
    int i = 0;
    while (!achou && i < valores.length) {
        if (n == valores[i]) {
            achou = true; // encontrei
        }
        i++;
    }
    return achou;
}

Mas eu ainda prefiro a versão que coloquei acima, com o return dentro do if mesmo. Criar uma flag só pra não usar return dentro do if (ou “só pra seguir a boa prática”) me parece um exagero, e o código - na minha opinião - não ficou melhor (tem casos em que ficará, mas é o que eu disse: varia muito, não tem essa de servir sempre pra todos os casos).

Sei lá, eu prefiro ser pragmático, em vez de seguir regras cegamente (que é o que muitos acabam fazendo com as tais “boas práticas”, muitas vezes sem perceber). Eu vejo as “boas práticas” como guias, recomendações gerais, “conselhos” de coisas que as pessoas viram que geralmente (mas não sempre) costumam “funcionar” em determinadas situações. Mas você sempre deve avaliar o contexto, em vez de seguir cegamente uma regra que nem sempre pode ser a ideal.

Eu entendo que para iniciantes é mais “fácil” e “confortável” simplesmente ensinar que “é assim porque assim é o certo” e pronto. Mas conforme vai-se adquirindo experiência, é sempre bom repensar essas “boas práticas” - claro que isso também não é desculpa para fazer tudo de qualquer jeito ou tentar sempre reinventar a roda (muitas práticas existem por um motivo, e podem te ajudar a não cometer erros bobos), mas senso crítico é sempre bom…