GMBR
Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.
Entrar

Esqueci-me da senha

Últimos assuntos
» player não consegue andar
por lovn7 Qui 21 Nov 2024, 13:33

» É possível fazer istó no game maker
por William Lima Qui 21 Nov 2024, 10:56

» Rio Rise - novo launcher do Gta San Andreas SAMP Brasil
por Lua Sáb 16 Nov 2024, 20:22

» (Resolvido) Cenario longo x Texture Pages
por josuedemoraes Sáb 16 Nov 2024, 15:31

» Kids' band
por Adilson Lucindo Santos Sex 15 Nov 2024, 12:23

» (RESOLVIDO) Engasgos-Troca de Sprites/animações
por josuedemoraes Ter 12 Nov 2024, 01:49

» Block Room - DEMO
por Joton Qua 06 Nov 2024, 22:58

» Game Infinito vertical (subindo)
por macmilam Sáb 26 Out 2024, 12:36

» Retorno da GMBR!!!
por Dancity Ter 22 Out 2024, 16:36

» Máquina de estados
por aminaro Qui 10 Out 2024, 13:33

» como faço pra um objeto colidir com o outro e diminuir a vida do player ?
por josuedemoraes Qui 03 Out 2024, 16:51

» RESOLVIDO: Colisão com objetos moveis
por josuedemoraes Qua 02 Out 2024, 20:28

» Crypt of the Blood Moon
por divin sphere Qua 11 Set 2024, 18:18

» como fazer um objeto seguir?
por divin sphere Dom 18 Ago 2024, 18:08

» Procuro de alguém para Modelar/Texturizar/Animar objetos 3D
por un00brn Dom 11 Ago 2024, 11:10

» Destruição de cenário (estilo DD Tank)
por CoronelZeg Sex 09 Ago 2024, 17:16

» RESOLVIDO-Como destruir uma instancia especifica de um objeto
por josuedemoraes Ter 23 Jul 2024, 00:40

» Automatizar a coleta de id
por GabrielXavier Seg 22 Jul 2024, 18:01

» Preciso de ajuda para concluir um pequeno projeto
por lmoura Qui 27 Jun 2024, 15:45

» ANGULO ACOMPANHAR O OBJETO
por Klinton Rodrigues Qui 27 Jun 2024, 08:34

» Musica reinicia quando sala reinicia
por GabrielXavier Ter 18 Jun 2024, 07:28

» como fazer uma copia de gd
por generico_cube Sex 14 Jun 2024, 15:48

» Square Adventure
por guilherme551 Ter 11 Jun 2024, 09:54

» como posso definir limite de uma variavel
por GabrielXavier Sex 07 Jun 2024, 14:14

» [Resolvido] Dúvida, colisão única de objeto
por vdm842 Sex 24 maio 2024, 09:50


Organizando condições (if e else)

Ir para baixo

Organizando condições (if e else) Empty Organizando condições (if e else)

Mensagem por M.A.S. Sáb 28 Mar 2009, 22:38

Artigo escrito por Neorevolutions, originário do site:
http://developers3.webcindario.com/articles/view.php?id=29&title=Organizando+blocos+if-else&PHPSESSID=1cc292ca2319952b4338ed094b881e2b

Introdução

Todo programador utiliza blocos de if-else, isso é certeza. Mas nem todo programador sabe utiliza-lo de maneira legível ou organizada, sendo ele experiente ou iniciante.

Dependendo de como se escreve um programa ou script, pode haver a necessidade de se utilizar grandes quantidades de blocos condicionais. Se há somente um ou dois blocos dentro de outro, não há muito motivo para se alarmar, mas quando a cadeia de blocos começa a aumentar, a legibilidade do código começa a diminuir drasticamente.


Blocos dentro de blocos

Toda confusão com blocos if-else começa quando se faz necessário que um determinado código somente seja executado após passar por uma série de testes. E em algumas ocasiões, a cada teste que falha, se necessita mostrar o erro ao cliente. Para se ter uma idéia do problema, veja o código abaixo:

Código:
if ( arquivo_existe )
{
    if ( arquivo_aberto )
    {
        if ( ler_linha_do_arquivo )
        {
            if ( linha_valida )
            {
                print( linha );
            }
            else
            {
                print("Linha inválida");
            }
        }
        else
        {
            print("Não foi possível ler a linha");
        }
    }
    else
    {
        print("Arquivo não aberto");
    }
}
else
{
    print("Arquivo não existe");
}

Esse código pode ser considerado horrível e o programador que escreve desta forma, deveria tentar corrigir o problema. Note que não existem tantos blocos if-else, mas mesmo assim dificulta um pouco seu entendimento.

Uma maneira melhor de se conseguir o mesmo objetivo do exemplo anterior, mas escrevendo de uma forma mais clara é não utilizando o else ou evitando de se colocar um bloco dentro de outro. Veja como ficaria o mesmo código escrito de outra forma.
Código:

if ( arquivo_existe == false )
{
    print("Arquivo não existe");
    return;
}

if ( arquivo_aberto == false )
{
    print("Arquivo não aberto");
    return;
}

if ( ler_linha_do_arquivo == false )
{
    print("Não foi possível ler a linha");
    return;
}

if ( linha_valida == false )
{
    print("Linha inválida");
    return;
}

print( linha );

Como pode ver, o bloco ficou mais legível, pois precisamos nos preocupar com um bloco de cada vez. No exemplo anterios teriamos que nos preocupar com o teste que está sendo lido no momento e também com os outros testes feitos anteriormente. Fica também mais dificil localizar onde está o código que irá ser executado se passar em todos os testes.

Além de tudo, o bloco else está muito longe de seu par, o que pode causar confusão em se saber qual else faz parte com um determinado if. Utilizando-se o segundo método pode eliminar ou pelo menos diminuir esse problema.

Esse primeiro exemplo não é dos piores, existem outros ainda mais confusos. Veja:

Código:
string erro;
status resultado;

resultado = abrir_arquivo( arquivo );
if ( resultado == status_erro )
{
    erro = "Arquivo nao aberto";
}
else
{
    resultado = ler_arquivo(arquivo, dados);
    if ( resultado == status_ok )
    {
        resultado = mostrar_dados( dados );
        if ( resultado == status_erro )
        {
            erro = "Dados invalidos";
        }
        else
        {
            resultado = salvar_dados( dados );
            if ( resultado == status_erro )
            {
                erro = "Dados não salvos";
            }
            else
            {
                limpar_dados( dados );
                erro = "Nenhum";
            }
        }
    }
    else
    {
        erro = "Erro de leitura";
    }
}


Esse código é dificil de se seguir por que os blocos de erro e estão misturados com os outros. Por este motivo, não é tão óbvio o caminho lógico a ser seguido. Um meio de se melhorar este código é utilizando o estilo do primeiro exemplo, mas isto também não seria a melhor solução. Veja como ficaria seguindo o estilo do primeiro exemplo:

Código:
string erro;
status resultado;

resultado = abrir_arquivo( arquivo );
if ( resultado == status_ok )
{
    resultado = ler_arquivo(arquivo, dados);
    if ( resultado == status_ok )
    {
        resultado = mostrar_dados( dados );
        if ( resultado == status_ok )
        {
            resultado = salvar_dados( dados );
            if ( resultado == status_ok )
            {
                limpar_dados( dados );
                erro = "Nenhum";
            }
            else
            {
                erro = "Dados não salvos";
            }
        }
        else
        {
            erro = "Dados invalidos";
        }
    }
    else
    {
        erro = "Erro de leitura";
    }
}
else
{
    erro = "Arquivo nao aberto";
}

Ficou mais legível, mas ainda não seria o ideal. Ainda há uma certa dificuldade em se perceber qual erro faz parte de qual teste. Para se aumentar a legibilidade, é prefirivel que este código fique isolado em uma função, retornando um status geral. Veja:

Código:
tipo_de_erro processar_arquivo( arquivo )
{
    status resultado;

    resultado = abrir_arquivo( arquivo );

    if ( resultado == status_erro )
        return Erro_Arquivo_Nao_Aberto;
       
    resultado = ler_arquivo(arquivo, dados);

    if ( resultado == status_erro )
        return Erro_Arquio_Nao_Lido;

    resultado = mostrar_dados( dados );

    if ( resultado == status_erro )
        return Erro_Dados_Invalidos;

    resultado = salvar_dados( dados );

    if ( resultado == status_erro )
        return Erro_Dados_Nao_Salvos;

    limpar_dados( dados );

    return Erro_Nenhum;
}

Perceba que ficou mais facil de se seguir a lógica pretendida e ainda melhorando a legibilidade desse código. Outro modo de se fazer a mesma coisa é o seguinte:
Código:

tipo_de_erro processar_arquivo( arquivo )
{
    if ( abrir_arquivo( arquivo ) == status_erro )
        return Erro_Arquivo_Nao_Aberto;
       
    if ( ler_arquivo(arquivo, dados) == status_erro )
        return Erro_Arquio_Nao_Lido;

    if ( mostrar_dados( dados ) == status_erro )
        return Erro_Dados_Invalidos;

    if ( salvar_dados( dados ) == status_erro )
        return Erro_Dados_Nao_Salvos;

    limpar_dados( dados );

    return Erro_Nenhum;
}

Este último código ficou ainda mais fácil de ser lido e entendido por qualquer um que o observe. Separando-se partes complexas em diferentes funções pode melhorar a legibilidade nos casos em que o tamanho das funções seja muito extenso.


Organizando conjuntos de testes

Outro problema que pode ocorrer num código é uma quantidade muito grande de testes relacionais ou lógicos. Isso tudo dentro de um único if.

Veja como seria um caso típico do problema:

Código:
if (
    indice < 0 ||
    indice > maximo ||
    indice == ultimo_indice ||
    dados_inseridos == false )
{
    print("Dados invalidos");
}

Esse é um exemplo simples, então ainda é legível. Mas se houvesse mais operadores relacionais e lógicos, o código se tornaria mais complexo e, portanto, mais dificil de se entender.

Veja como criar um código mais legível se um dia encontrar uma situação parecida.

Código:
bool indice_invalido = (indice < 0 || indice > maximo);
bool indice_repetido = (indice == ultimo_indice);
bool dados_inexistentes = (dados_inseridos == false );
if ( indice_invalido || indice_repetido || dados_inexistentes)
    print("Dados invalidos");
[code]

Este método clarifica o entendimento por ser mais fácil de se ler, pois fica parecido com uma lingua real ao invés de uma linguagem de programação.

O que seria mais fácil de se entender?

A: Se o indice for menor que zero ou o indice for maior que o máximo ou o indice é o mesmo que o anterior ou os dados não foram inseridos, então faça tal coisa.
B: Se o indice é inválido ou se o indice for repetido ou se os dados não foram inseridos, faça tal coisa.

Provavelmente respondeu B.

Hoje em dia, com a capacidade dos computadores, criar 3 ou 4 variáveis a mais praticamente não influencia na performance geral.


Conclusão

Todas estas informações são apenas dicas para todos os programadores que queiram melhorar seus códigos. Nada os impede de ignorá-las e seguir com o mesmo estilo. Mas será que há algo que o impeça de utilizá-los e criar códigos mais legíveis?

Assimo como qualquer dica, utilize apenas os que achar necessarios ou que for apropriado para cada situação.
M.A.S.
M.A.S.

Data de inscrição : 03/01/2009
Reputação : 0
Número de Mensagens : 377
Prêmios : Organizando condições (if e else) Empty

Medalhas x 0 Tutoriais x 0 Moedas x 0

Ouro x 0 Prata x 0 Bronze x 0

Insignia 1 x 0 Insignia 2 x 0 Insignia 3 x 0

Ir para o topo Ir para baixo

Ir para o topo

- Tópicos semelhantes

 
Permissões neste sub-fórum
Não podes responder a tópicos