Question

Je suis curieux de voir des alternatives aux déclarations régulières si telles que

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

afin que vous voyez tous si les déclarations sont séparées et aucune autre condition. S'il vous plaît noter que X Y Z sont des conditions totalement distinctes afin commutateur ne conviendrait pas.

Était-ce utile?

La solution

Un "véritablement orienté objet" La réponse serait de définir une interface pour " Règle " (avec les méthodes condition () et action ()), créez 3 implémentations, insérez-les dans une collection, puis parcourez-les simplement de manière générique, comme dans:

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

Cela est beaucoup plus logique si vous avez 300 règles / conditions au lieu de 3.

Sous Java8, vous pouvez le faire à la place, si les règles consomment beaucoup de ressources processeur:

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

Autres conseils

La réponse courte est oui.

Vous pouvez éviter d’utiliser un peu de temps en cas d’évaluation conditionnelle et d’embranchement simultané. Et ils ont des moments de pertinence.

  1. Polymorphisme lorsque le comportement dépend des valeurs initiales
  2. Assignation référencée, lorsque vous connaissez les valeurs initiales possibles et qu'elles ont une corrélation de 1 à 1 avec les valeurs de retour. Les listes sont meilleures que les tableaux pour cela, mais ...
       

    // 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. Branchement référencé, lorsque vous connaissez les valeurs initiales possibles et qu’elles ont une corrélation de 1 à 1 avec la fonction / branche à utiliser. (exemple pas 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. Affectation booléenne directe.

    Nous détestons:

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

    Devrait être:

      

    b = thisCondition;

Les alternatives à if-else en Java sont l'instruction switch et le ternaire conditionnel (?: ), aucun des deux ne faisant exactement ce que vous demandez (gérer uniquement un si sans else ). Le code que vous avez posté est la meilleure façon de le faire, à mon avis.

Utiliser le polymorphisme.

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

Le if n'est pas complètement éliminé, mais il est déplacé dans SomethingDoerFactory. Cette solution n’est pas applicable dans tous les cas, mais dans certains d’entre eux, elle constitue une très bonne alternative aux multiples ifs.

Voici une belle conversation à ce sujet:
http://misko.hevery.com / 2008/12/08 / tests de codage du polymorphisme sur l'héritage du code clair /

C’est la solution la plus simple, lisible mais efficace . Je serais surpris de voir des alternatives efficaces ici.

EDIT

vous pouvez essayer d'appliquer la méthode d'extraction à plusieurs reprises:

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

où les méthodes sont définies par:

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

    // do 'a'
}

cela dépend vraiment de ce que x, y, z et a, b, c sont. Parfois, si les déclarations sont plus appropriées. Parfois, le polymorphisme est plus approprié.

Vous aurez besoin de ces déclarations if quelque part.

Ils peuvent être transformés en d’autres méthodes pour garder la méthode actuelle propre, comme d’autres l’ont suggéré. Si vous devez réutiliser le même ensemble d’instructions if à plusieurs endroits, il peut-être utiliser le Modèle de décorateur .

Cela semble être le cas idéal pour utiliser la fermeture . Mais pour cela, vous avez besoin de groovy ou de quelque chose de similaire.

que diriez-vous de ... myAnimator (chose, pos, vitesse | computeSpeed ??());

si speed === indéfini il calculera alorsSpeed ??... je pense.

Cela dépend vraiment du contexte ... mais oui, si-else n'est qu'une des déclarations du flux de contrôle en java: https://docs.oracle.com/javase/tutorial/java/ nutandbolts / flow.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top