web-dev-qa-db-fra.com

Devrait "sinon" être utilisé dans des situations où le flux de contrôle le rend redondant?

Je tremble parfois du code similaire à celui de l'exemple suivant (que cette fonction est exactement hors de la portée de cette question):

function doSomething(value) {
  if (check1(value)) {
    return -1;
  }
  else if (check2(value)) {
    return value;
  }
  else {
    return false;
  }
}

Comme vous pouvez le constater, if, else if et else _ Les instructions sont utilisées conjointement avec la déclaration return. Cela semble assez intuitif à un observateur occasionnel, mais je pense qu'il serait plus élégant (du point de vue d'un développeur de logiciels) de supprimer le else- s et simplifier le code comme celui-ci:

function doSomething(value) {
  if (check1(value)) {
    return -1;
  }
  if (check2(value)) {
    return value;
  }
  return false;
}

Cela donne un sens, comme tout ce qui suit une déclaration return (dans la même portée) ne sera jamais exécuté, ce qui rend le code ci-dessus par sémantiquement égal au premier exemple.

Lequel de ce qui précède convient à la bonne pratique de codage plus? Existe-t-il des inconvénients à l'une ou l'autre méthode en ce qui concerne la lisibilité du code?

Edit: une suggestion en double a été faite avec cette question fournie comme référence. Je crois que ma question touche à un sujet différent, car je ne demande pas d'éviter les déclarations en double telles que présentées dans l'autre question. Les deux questions cherchent à réduire les répétitions, bien que de manière légèrement différente.

19
rhino

J'aime celui sans else et voici pourquoi:

function doSomething(value) {
  //if (check1(value)) {
  //  return -1;
  //}
  if (check2(value)) {
    return value;
  }
  return false;
}

Parce que cela n'a rien brisé, ce n'était pas censé.

Haine interdépendance dans tous ses formes (y compris nommer une fonction check2()). Isoler tout ce qui peut être isolé. Parfois, vous avez besoin de else mais je ne vois pas cela ici.

23
candied_orange

Je pense que cela dépend de la sémantique du code. Si vos trois cas dépendent de l'autre, indiquez-le explicitement. Cela augmente la lisibilité du code et facilite la compréhension de quiconque. Exemple:

if (x < 0) {
    return false;
} else if (x > 0) {
    return true;
} else {
    throw new IllegalArgumentException();
}

Ici, vous dépendez clairement de la valeur de x dans les trois cas. Si vous omettez le dernier else, cela serait moins clair.

Si vos cas ne dépendent pas directement les uns sur les autres, omettez-le:

if (x < 0) {
    return false;
}
if (y < 0) {
    return true;
}
return false;

Il est difficile de montrer cela dans un exemple simple sans contexte, mais j'espère que vous aurez mon point.

28
André Stannek

Je préfère la deuxième option (séparé ifs sans else if et tôt return) MAIS C'est Tant que les blocs de code sont courts.

Si les blocs de code sont longs, il est préférable d'utiliser else if, parce que, d'autres ci-dessus, vous n'auriez pas de compréhension claire des points de sortie de plusieurs exits, le code a.

Par exemple:

function doSomething(value) {
  if (check1(value)) {
    // ...
    // imagine 200 lines of code
    // ...
    return -1;
  }
  if (check2(value)) {
    // ...
    // imagine 150 lines of code
    // ...
    return value;
  }
  return false;
}

Dans ce cas, il est mieux utilisé else if, stockez le code de retour dans une variable et je n'ai qu'une phrase de retour à la fin.

function doSomething(value) {
  retVal=0;
  if (check1(value)) {
    // ...
    // imagine 200 lines of code
    // ...
    retVal=-1;
  } else if (check2(value)) {
    // ...
    // imagne 150 lines of code
    retVal=value;
  }
  return retVal;
}

Mais comme on pourrait s'efforcer de courir pour que les fonctions soient courtes, je dirais que le garder court et sortir tôt comme dans votre premier extrait de code.

6
Tulains Córdova

J'utilise les deux dans des circonstances différentes. Dans un chèque de validation, je omettons l'autre. Dans un flux de contrôle, j'utilise l'autre.

bool doWork(string name) {
  if(name.empty()) {
    return false;
  }

  //...do work
  return true;
}

vs

bool doWork(int value) {
  if(value % 2 == 0) {
    doWorkWithEvenNumber(value);
  }
  else {
    doWorkWithOddNumber(value);
  }
}

Le premier cas lit plus comme si vous vérifiez d'abord toutes les conditions préalables, que ce soit à l'écart, puis évoluant vers le code réel que vous souhaitez exécuter. En tant que tel, le code juteux que vous souhaitez vraiment courir appartient directement à la portée de la fonction; C'est à quoi ressemble vraiment la fonction.
[.____] Le deuxième cas lit plus que les deux chemins sont un code valide à exécuter qui sont tout aussi pertinents pour la fonction que l'autre en fonction de certaines conditions. En tant que tel, ils appartiennent à des niveaux de portée similaires.

4
Altainia