Pergunta

Estou curioso para ver qualquer alternativa (s) para o regular se declarações como

if(x)
     do a;
if(y)
     do b;
if(z)
    do c;

Então, como você ver tudo, se as declarações são separados e nenhuma condição de pessoa. Por favor note que X Y Z são condições totalmente separadas de modo interruptor que não se encaixam.

Foi útil?

Solução

Uma resposta "verdadeiramente orientada a objeto" seria definir uma interface para "Regra" (com a condição () e métodos de ação ()), criar 3 implementações, enchê-los em uma coleção, e depois é só iterate através deles genericamente como em:

List<Rule> rules = .... ; // your 3 rules initialized here somehow
for(Rule r : rules) {
  if(r.condition()) {
    r.action();
  }
}

Isso faz muito mais sentido se você tem 300 regras / condições em vez de apenas 3.

Em Java8, você pode querer fazer isso em vez disso, se as regras são intensiva da CPU:

rules.parallelStream().filter(Rule::condition).forEach(Rule::action);

Outras dicas

A resposta curta é sim.

Há pouco tempo você pode evitar o uso se para evluation condicional e ramificação todos juntos. E eles têm momentos de adequação.

  1. Polimorfismo, quando o comportamento é dependente dos valores iniciais
  2. referrenced Assignment, quando você conhece os possíveis valores iniciais e eles têm 1-1 correlação com os valores de retorno. Listas são melhores do que as matrizes para isso, mas ...

    // Example:  
    if (a==1) { b=2;  }  
    if (a==2) { b=17; }  
    
    // Becomes  
    int fx(2);  // our array of answers  
    fx[0] = 2;   
    fx[1] = 17;  
    b = fx[ a - 1 ];
    
  3. referrenced ramificação, quando você conhece os possíveis valores iniciais e eles têm 1-1 correlação com a função / galho em uso. (Exemplo não Java)

    // Example:
    if (a==1) { doSomething1();  }  
    if (a==2) { doSomething2(); }  
    
    // Becomes
    function * fx(2);  // our array or better still, list of functions  
    fx[0] = &doSomething1;   
    fx[1] = &doSomething2;  
    `fx[ a - 1 ](); `
    
  4. atribuição boolean Direct.

    Nós odiamos:

    if (thisCondition == true) {  
      b = true;  
    } else {  
      b = false;  
    }
    

    Deve ser:

    b = thisCondition;

As alternativas para if-else em Java são a instrução switch eo condicional ternário (: ) operador, nenhum dos quais fazer exatamente o que você está pedindo (punho apenas uma if sem else). O código que você postou é a melhor maneira de fazê-lo, na minha opinião.

Use polimorfismo.

interface SomethingDoer {
    public void doSomething();
}

class ADoer implements SomethingDoer { ... }
class BDoer implements SomethingDoer { ... }
class CDoer implements SomethingDoer { ... }

public class Main {
     public static void main (String[] args) {
          SomethingDoer doer = new SomethingDoerFactory(args).getDoer();
          doer.doSomething();
     }
}

O caso não é totalmente eliminado, mas ele é movido para SomethingDoerFactory. Esta solução não é aplicável em todos os casos, mas em alguns deles, é uma alternativa muito boa para vários ifs.

Aqui está uma boa conversa sobre isso:
http://misko.hevery.com / 2008/12/08 /-código limpo-fala-herança-polimorfismo testando /

este é o mais simples, legível, mas eficaz solução. Eu ficaria surpreso de ver alternativas eficazes aqui.

Editar

Você pode tentar aplicar método extrato várias vezes:

doAIfX();
doBIfY();
doCifZ();

onde os métodos são definidos por:

void doAIfX() {
    if (!X) {
        return;
    }

    // do 'a'
}

isso realmente depende do que x, y, z e a, b, c são. Às vezes, se as declarações são mais adequados. Às vezes, o polimorfismo é mais adequado.

Você precisa ter estes se declarações em algum lugar.

Eles podem ser reformulado em outros métodos para manter o presente método limpo, como já foi sugerido. Se você precisa re-utilizar esta mesma set de se declarações em um número de lugares, ele pode ser possível o uso do Decorator Pattern .

Parece um caso perfeito para o uso de fechamento . Mas para isso você precisa Groovy ou algo similar.

Que tal ... myAnimator (coisa, pos, velocidade | computeSpeed ??());

Se a velocidade === indefinido que, em seguida, vai computeSpeed ??... eu acho.

É realmente depende do contexto ... mas sim if-else é apenas um dos fluxo de controle declaração em java: https://docs.oracle.com/javase/tutorial/java/ nutsandbolts / flow.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top