Come gestire l'indicatore in più se-else

10

Mi sembra di capirlo abbastanza spesso nel mio codice e in altri. Non c'è niente che sembra terribilmente sbagliato, ma mi infastidisce perché sembra che possa essere fatto meglio. Suppongo che una dichiarazione di un caso, potrebbe avere un po 'più senso, ma spesso variabile è un tipo che non funziona bene o del tutto con le dichiarazioni dei casi (a seconda della lingua)

If variable == A
    if (Flag == true)
        doFooA()
    else
        doFooA2

else if variable == B
    if (Flag == true)
        doFooB()
    else
        doFooB2
else if variable == C
    if (Flag == true)
        doFooC()
    else
        doFooC2

Sembra che ci siano molti modi per "fattore" di questo, come 2 set di if-els, in cui un set gestisce quando Flag == true.

C'è un "buon senso" per tenerlo in considerazione, o forse quando questo algoritmo if-else accade di solito significa che stai facendo qualcosa di sbagliato?

    
posta TruthOf42 10.06.2013 - 21:02
fonte

5 risposte

18

Potrebbe essere gestito con il polimorfismo.

factory(var, flag).doFoo();

Ogni volta che si ha una serie di controlli if / else sul tipo di qualcosa, si potrebbe considerare di centralizzare il controllo if / else in un metodo factory, quindi chiamare doFoo () polimorficamente. Ma questo potrebbe essere over-kill per una soluzione 1-off.

Forse potresti creare una mappa chiave / valore in cui la chiave è var / flag e il valore è la funzione stessa.

do[var, flag]();
    
risposta data 10.06.2013 - 21:25
fonte
6

I nested multipli aumentano la complessità ciclomatica del codice. Fino a poco tempo fa, avere più punti di uscita in una funzione era considerato un codice strutturato male, ma ora, se il codice è semplice e breve , puoi farlo, rendendo banale il codice da leggere:

    if (variable == A && Flag) {
        doFooA();
        return;
    }

    if (variable == A) {
        doFooA2();
        return;
    }

    if (variable == B && Flag){
        doFooB();
        return;
    }

    if (variable == B){
        doFooB2();
        return;
    }

    if (variable == C && Flag){
         doFooC();
         return;
    }

    if (variable == C){
         doFooC2();
    }

    return;
    
risposta data 11.06.2013 - 02:42
fonte
3

un'altra opzione è combinare if e switch. Questo non è superiore alla tua tecnica se nidificata, ma può ridurre il numero di test duplicati (se lo switch si ottimizza su una tabella di salto).


if (flag)
{
    switch (variable)
    {
        case A:
           ... blah
           break;

        case B:
           ... blah
           break;

        case C:
           ... blah
           break;

        default:
           ... log an error.
           ... maybe do a default action.
           break;
    }
}
else // flag == false
{
    switch (variable)
    {
        case A:
           ... blah
           break;

        case B:
           ... blah
           break;

        case C:
           ... blah
           break;

        default:
           ... log an error.
           ... maybe do a default action.
           break;
}
    
risposta data 11.06.2013 - 20:30
fonte
0

Bene, c'è sempre questo ...

if variable == A && Flag
    doFooA()
else if variable == A 
    doFooA2    
else if variable == B && Flag
    doFooB()
else if variable == B
    doFooB2
else if variable == C && Flag
     doFooC()
else if variable == C
     doFooC2

Ma francamente, penso che il codice originale non sia male male in primo luogo.

    
risposta data 11.06.2013 - 01:47
fonte
0

Utilizza il polimorfismo e una matrice rule

interface IRule() {
  boolean applicable(args...);
  obj apply(args...);
}

static final Array<IRule> rules = [new MeaningfulNameRule1(), new MeaningfulNameRule2(), ...];

/* where */
class MeaningfulNameRuleX extends IRule{ /* */ }

/* In your method */

for (rule in rules) {
  if (rule.applicable(a,b,c)){
    return rule.apply(e,f,g);
  }
}

O come mike30 suggerito: se le condizioni della regola possono facilmente formare una chiave, allora una hashmap è il modo migliore per andare.

    
risposta data 17.06.2013 - 22:08
fonte

Leggi altre domande sui tag