Controlar fluxo de dados

Objetivos de aprendizagem

Após concluir esta unidade, você estará apto a:

  • Listar os usos dos operadores de comparação.
  • Descrever a diferença entre as instruções switch e if-else.

Em nossas vidas cotidianas, sempre há decisões a tomar. O que eu uso? O que eu como? Devo ir para a esquerda ou para a direita? A mesma coisa acontece ao escrever código. Pense em nosso pseudocódigo Teatime da unidade 1, especificamente no passo 2. 

Boil water in a Tea Kettle
Fill Kettle with Water
Switch Kettle On
Wait for Water to Boil

Humm... tudo parece bem correto, não é? Para ferver água, encho a chaleira de água, ligo a chaleira e espero que a água ferva. Mas e se já houver água na chaleira? E se a chaleira estiver cheia? Quanto tempo a água deve ferver?

Expressões e operadores de expressão

Antes de tomarmos decisões, costumamos fazer comparações. Isso é maior que aquilo? Isso é igual àquilo? Os desenvolvedores costumam comparar valores antes de tomar decisões em seus aplicativos. No código, comparamos duas expressões colocando um operador de expressão entre elas. 

Uma expressão é um trecho de código que, quando avaliado, resulta em um único valor. Para nossos objetivos neste módulo, uma expressão pode ser um valor literal (como 12), ou uma variável (como numberOfTeaCups), ou uma operação matemática (como 7 x 4).

Os operadores de expressão comparam ou mostram igualdade entre dois valores. Uma instrução de comparação consiste em duas expressões separadas por um operador de expressão e produz um valor booleano, seja verdadeiro ou falso. 

Operadores de comparação

Operador
Descrição
Sintaxe
Resultado
<
Menor que
1 < 2
TRUE
<=
Menor que ou igual a
1 <= 2
3 <= 3
VERDADEIRO
==
Igual a
10 == 10
TRUE
!=
<>
Não é igual a
10 != 0
10 <> 11
VERDADEIRO
>
Maior que
11 > 10
TRUE
>=
Maior ou igual a
40 >=10
40 >= 40
VERDADEIRO

Por que o operador igual a tem dois sinais de igual? Lembre-se de que usamos um único sinal de igual nesta instrução:

Integer i = 2;

Um sinal de igual (=) é um operador de atribuição. Ele atribui valores. Dois sinais de igual (==) é um operador de comparação. Ele compara dois valores para determinar se eles são iguais (verdadeiro) ou não iguais (false).

Os operadores são particularmente úteis quando você deseja comparar um valor conhecido com uma variável ou comparar os valores de duas variáveis diferentes. 

Integer numberOfTeaCups = 2;
numberOfTeaCups == 3;  //false
numberOfTeaCups == 2; //true

Vimos um exemplo de uma variável de número inteiro e uma variável de cadeia de caracteres. Também podemos criar uma variável booleana que contém o resultado de uma comparação. Confira:

Integer numberOfTeaCups = 2;
Boolean result = numberOfTeaCups > 3; // 2 > 3 = false

A linha 1 define a variável numberOfTeaCups como 2.

A linha 2 cria uma variável de tipo booleano chamada result, compara o valor de variável numberOfTeaCups ao número 3 e atribui o resultado da comparação (false) à variável result

Embora as comparações sejam úteis para determinar como uma coisa se relaciona com outra, onde elas realmente brilham é dentro de instruções condicionais, onde elas ajudam a tomar decisões.

Instruções condicionais

Os desenvolvedores usam expressões dentro de instruções condicionais para criar estruturas de tomada de decisão que especificam uma ou mais condições a serem avaliadas ou testadas pelo programa. Uau, isso é muita coisa. Vamos entender isso melhor.

Uma instrução condicional configura duas ou mais opções. Se você já criou critérios no Process Builder, você usou uma instrução condicional. Por exemplo, "se o estado for igual a Califórnia, então exiba registros no modo de exibição de lista" é uma instrução condicional. "Estado igual a Califórnia" é a  condição e "exibir registros no modo de exibição de lista" é a ação que o programa toma somente quando a condição é verdadeira. Neste exemplo, as duas opções são exibir registros (explícita) e não exibir registros (implícita).

Instruções if-else
Uma instrução condicional comumente usada no Apex é a instrução if-else. Fica assim:

if (condition is true){
    //do this
}else{
    //do this
}

A Linha 1 define a condição (escrita em parênteses).
A Linha 2 contém o código a ser executado se a condição na Linha 1 for true.
A Linha 3 apresenta a segunda opção, a opção else.
A Linha 4 contém o código a ser executado se a condição na Linha 1 for false.

No Apex, colocamos instruções condicionais dentro de chaves: { }. Quando uma chave é aberta, { precisa haver outra chave para fechar, } que acompanha esse bloco de código.

Vamos usar uma instrução condicional em nosso pseudocódigo Teatime para verificar o nível de água na chaleira e decidir o que fazer a seguir com base no nível da água.

  1. No Developer Console, clique em Debug (Depurar) | Open Execute Anonymous Window (Abrir a janela Executar anônimo).
  2. Copie esse código e cole-o na janela Enter Apex Code (Inserir código do Apex).
  3. String waterLevel = 'full'; /*This variable keeps track of the water level status: full or empty*/
    if(waterLevel == 'empty'){
        System.debug('Fill the tea kettle');
        waterLevel = 'full'; /*Once the tea kettle is filled the variable is changed to full*/
    }else{
        System.debug('The tea kettle is full');
    }
  4. Marque a caixa de seleção Open Log (Abrir registro) e clique em Execute (Executar).
  5. O log de execução abre, exibindo o resultado da execução do seu código. Selecione a caixa de seleção Debug Only (Depurar somente) na parte inferior da janela.

Na linha 1, inicializamos a variável waterLevel como full. Geralmente, os valores de variável no código são inseridos por usuários ou derivados de outros dados, não especificados no próprio código. No nosso exemplo Teatime, teríamos dados físicos dos sensores na chaleira para determinar o nível da água. Quando esses dados estão indisponíveis, os desenvolvedores definem valores diretamente no código (temporariamente) para que eles possam executar o código e testá-lo. A configuração dos valores no código é chamada de hard-coding ou codificação. Para fins de teste, codificamos o valor full da variável waterLevel. Como esse valor já foi definido, a primeira instrução if (linha 2) nunca será executada, pois o waterLevel nunca começará com o valor empty

O código verifica se a variável waterLevel é igual a empty. Como codificamos o waterLevel full, a condição de instrução if é falsa. Quando a condição if é falsa, o bloco de código else é executado. 

Nosso código atualmente lida com duas condições: o nível da água está full (cheio) e o nível de água está empty (vazio). Mas essas não são as únicas possibilidades, certo? A chaleira pode estar parcialmente cheia. Como lidamos com mais de duas possibilidades? 

Instruções if-else-if
Para lidar com mais de duas possibilidades, usamos uma instrução if-else-if. A instrução if-else-if adiciona outra condição if antes da condição else final. Vamos ver um exemplo em ação.

  1. No Developer Console, clique em Debug (Depurar) | Open Execute Anonymous Window (Abrir a janela Executar anônimo).
  2. Copie esse código e cole-o na janela Enter Apex Code (Inserir código do Apex).
  3. String waterLevel = 'half';
    if(waterLevel == 'empty'){
        System.debug('Fill the tea kettle');
        waterLevel = 'full';
    }else if(waterLevel == 'half'){
        System.debug('Fill the tea kettle');
        waterLevel = 'full';
    }else{ /*This statement only runs if line 2 and line 5 result in false.*/
        System.debug('The tea kettle is full');
    }
  4. Marque a caixa de seleção Open Log (Abrir registro) e clique em Execute (Executar).
  5. O log de execução abre, exibindo o resultado da execução de seu código. Marque a caixa de seleção Debug Only (Depurar somente) na parte inferior da janela.

Ao testar o código, altere o valor da variável waterLevel na linha 1. A saída no log de depuração reflete a alteração. Tente todos os três valores: half, full e empty.

Organize instruções condicionais para que a primeira condição seja a mais comum. Essa organização reduz a quantidade de código que é executado sempre que o bloco de código é executado. No nosso exemplo Teatime, a chaleira tem mais probabilidade de estar vazia, então colocamos essa condição em primeiro lugar. Não é provável que a chaleira esteja cheia e, por isso, vamos verificar essa condição por último. 

Instruções switch

Uma alternativa mais eficiente a uma instrução if-else  é uma instrução switch. Uma instrução switch especifica um conjunto de valores e testa uma expressão para determinar se ela corresponde a um desses valores. Veja como fica:

switch on expression{
    when value1{
        //code block 1
    }
    when value2{
        //code block 2
    }
    when else{ //if none of the previous values apply
        //code block 3
    }
}

Em uma instrução switch, você pode ter um ou mais valores após a palavra reservada when

switch on expression{
    when value1{ //single value
        //code block 1
    }
    when value2, value3{ //multiple values
        //code block 2
    }
}

Vamos aplicar switches ao nosso pseudocódigo Teatime.

  1. No Developer Console, clique em Debug (Depurar) | Open Execute Anonymous Window (Abrir a janela Executar anônimo).
  2. Copie esse código e cole-o na janela Enter Apex Code (Inserir código do Apex).
  3. String waterLevel = 'empty';
    //option 1 using a single value
    switch on waterLevel{
        when 'empty'{
            System.debug('Fill the tea kettle');
        }
        when 'half'{
            System.debug('Fill the tea kettle');
        }
        when 'full'{
            System.debug('The tea kettle is full');
        }
        when else{
            System.debug('Error!');
        }
    }
    //option 2 using multiple values
    switch on waterLevel{
        when 'empty', 'half'{ //when waterLevel is either empty or half
            System.debug('Fill the tea kettle');
        }
        when 'full'{
            System.debug('The tea kettle is full');
        }
        when else{
            System.debug('Error!');
        }
    }
  4. Marque a caixa de seleção Open Log (Abrir registro) e clique em Execute (Executar).
  5. O log de execução abre, exibindo o resultado da execução do seu código. Selecione a caixa de seleção Debug Only (Depurar somente) na parte inferior da janela.

Operadores lógicos

Você já sabe como lidar com duas ou mais condições. Agora, o que você faz quando uma única condição pode ser satisfeita por mais de um valor? 

Operadores lógicos

Operador OR AND
Símbolo do operador || &&
Pseudocódigo Se X ou Y, faça isso.
Caso contrário, faça isso.
Se X e Y, faça isso.
Caso contrário, faça isso.
Código do Apex Se (X || Y {
//faça isso
} ou {
//faça isso
}

Se (X || Y {
//faça isso
} ou {
//faça isso
}

Os operadores lógicos and e or permitem que você escreva um código que verifica mais de um valor para determinar se uma condição é verdadeira ou falsa. O operador and exige que todos os valores sejam verdadeiros para satisfazer a condição. O operador or exige que pelo menos um dos valores seja verdadeiro para satisfazer a condição.

Avaliação de operadores lógicos

Operador lógico
Sintaxe
Descrição
&& (AND)
X && Y

System.debug(true && true); // true

System.debug(false &&  true); //false

System.debug(true && false); // false

System.debug(false && false); //false
X e Y são valores booleanos. Se X e Y forem verdadeiros, a expressão é verdadeira. Caso contrário, a expressão é falsa.
|| (OR)
X || Y

System.debug(true || true);  //true

System.debug(false || true); //true

System.debug(true || false); //true

System.debug(false || false); //false
X e Y são valores booleanos. Se X e Y forem falsos, a expressão é falsa. Caso contrário, a expressão é verdadeira.

Vamos experimentar operadores lógicos. Aqui está nosso código quando ele foi escrito como uma instrução if-else-if.

String waterLevel = 'half';
if(waterLevel == 'empty'){
    System.debug('Fill the tea kettle');
    waterLevel = 'full';
}else if(waterLevel == 'half'){
    System.debug('Fill the tea kettle');
    waterLevel = 'full';
}else{ //This statement only runs if line 3 and line 6 result in false.
    System.debug('The tea kettle is full');
}

Veja as linhas 3-4 e linhas 6-7. Elas são idênticas. Chamamos isso de código redundante. A eliminação da redundância é uma prática recomendada porque torna o código mais legível e fácil de entender, depurar e manter. Nosso código executa as mesmas ações quer o waterLevel esteja empty ou half. Podemos simplificar esse código combinando empty e half em uma condição. Usamos o operador or para que a condição seja satisfeita quando um valor (empty ou half) for verdadeiro.

  1. No Developer Console, clique em Debug (Depurar) | Open Execute Anonymous Window (Abrir a janela Executar anônimo).
  2. Copie esse código e cole-o na janela Enter Apex Code (Inserir código do Apex).
  3. String waterLevel = 'half';
    if(waterLevel == 'empty' || waterLevel == 'half'){
        System.debug('Fill the tea kettle');
        waterLevel = 'full';
    }else{ //This statement only runs if line 3 false.
        System.debug('The tea kettle is full');
    }
  4. Marque a caixa de seleção Open Log (Abrir registro) e clique em Execute (Executar).
  5. O log de execução abre, exibindo o resultado da execução do seu código. Selecione a caixa de seleção Debug Only (Depurar somente) na parte inferior da janela.

Opa, olha só! Removemos nossa redundância de código. Usar operadores lógicos (&& e ||) é uma maneira eficaz de remover ou reduzir o código redundante e melhorar a legibilidade.

Mantenha seu código limpo

Na programação, muitas vezes você tem mais de uma maneira de fazer algo. Por exemplo, você pode usar instruções switch ou if-else e chegar ao mesmo resultado. O importante de pensar quando você seleciona um tipo de instrução a ser usada é como cada uma afeta a legibilidade do seu código. À medida que você continua trabalhando com código, você aprende mais maneiras de manter seu código limpo. Por enquanto, concentre-se em tornar seu código fácil de ler e entender. 

Recursos