Domanda

Sono curioso di vedere eventuali alternative al normale if dichiarazioni come

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

così come vedi tutto se le istruzioni sono separate e nessun'altra condizione. Si noti che X Y Z sono condizioni totalmente separate, quindi l'interruttore non si adatta.

È stato utile?

Soluzione

Uno "veramente orientato agli oggetti" la risposta sarebbe quella di definire un'interfaccia per "Rule" (con i metodi condition () e action ()), crea 3 implementazioni, inseriscile in una raccolta e quindi esegui l'iterazione generica come in:

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

Questo ha molto più senso se hai 300 regole / condizioni anziché solo 3.

In Java8, potresti preferire farlo, se le regole richiedono molta CPU:

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

Altri suggerimenti

La risposta breve è sì.

Ci sono alcune volte che puoi evitare di usare se per l'evaporazione condizionale e la ramificazione tutti insieme. E hanno momenti di appropriatezza.

  1. Polimorfismo, quando il comportamento dipende dai valori iniziali
  2. Assegnazione referrenziata, quando si conoscono i possibili valori iniziali e hanno una correlazione da 1 a 1 con i valori restituiti. Gli elenchi sono meglio degli array per questo, ma ...
       

    // 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. Branching referenziato, quando si conoscono i possibili valori iniziali e hanno una correlazione da 1 a 1 con la funzione / ramo da utilizzare. (esempio non 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. Assegnazione booleana diretta.

    Odiamo:

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

    Dovrebbe essere:

      

    b = thisCondition;

Le alternative a if-else in Java sono l'istruzione switch e la ternary condizionale (?: ), nessuno dei quali fa esattamente quello che stai chiedendo (gestisci solo un se senza else ). Il codice che hai pubblicato è il modo migliore per farlo, secondo me.

Usa il 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();
     }
}

L'if non viene completamente eliminato, ma viene spostato in SomethingDoerFactory. Questa soluzione non è applicabile in tutti i casi, ma in alcuni di essi è un'ottima alternativa a più if.

Ecco un bel discorso a riguardo:
http://misko.hevery.com / 2008/12/08 / clean-code-colloqui-eredità-polimorfismo-testing /

questa è la soluzione più semplice, leggibile ma efficace . Sarei sorpreso di vedere alternative efficaci qui.

Modifica

puoi provare ad applicare metodo di estrazione più volte:

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

dove i metodi sono definiti da:

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

    // do 'a'
}

dipende davvero da cosa sono x, y, z e a, b, c. A volte se le dichiarazioni sono più adatte. A volte il polimorfismo è più adatto.

Dovrai avere queste istruzioni if ??da qualche parte.

Possono essere rifattorizzati in altri metodi per mantenere pulito il metodo attuale, come altri hanno suggerito. Se devi riutilizzare lo stesso set di if istruzioni in più punti, potrebbe essere possibile utilizzare Motivo decorativo .

Sembra un caso perfetto per l'utilizzo della chiusura . Ma per questo hai bisogno di groovy o qualcosa di simile.

Che ne dici di ... myAnimator (cosa, pos, velocità | computeSpeed ??());

se speed === undefined calcolerà poi Speed ??... credo.

Dipende molto dal contesto ... ma sì, if-else è solo una delle istruzioni flusso di controllo in java: https://docs.oracle.com/javase/tutorial/java/ nutsandbolts / flow.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top