web-dev-qa-db-fra.com

Quand utiliser les instructions If-else si-else sur switch et vice versa

Pourquoi voudriez-vous utiliser un bloc switch sur une série d'instructions if?

Les instructions switch semblent faire la même chose mais prennent plus de temps à taper.

73
K2J

Comme pour la plupart des choses, vous devez choisir laquelle utiliser en fonction du contexte et de la méthode à adopter sur le plan conceptuel. Un commutateur dit en réalité "choisissez l'une de ces options en fonction de cette valeur de variable", mais une instruction if est simplement une série de vérifications booléennes.

Par exemple, si vous faisiez:

int value = // some value
if (value == 1) {
    doThis();
} else if (value == 2) {
    doThat();
} else {
    doTheOther();
}

Cela serait beaucoup mieux représenté comme un commutateur, car il est alors évident que le choix de l’action se fait en fonction de la valeur de "valeur" et non d’un test arbitraire.

De même, si vous écrivez des commutateurs et des if-els et que vous utilisez un langage OO, vous devriez envisager de vous en débarrasser et d'utiliser le polymorphisme pour obtenir le même résultat, si possible.

Enfin, pour ce qui est de la durée de frappe du commutateur, je ne me souviens plus qui l’a dit, mais j’ai lu une fois que quelqu'un me demandait: "Est-ce que votre vitesse de frappe est vraiment ce qui affecte votre vitesse de code?" (paraphrasé)

68
tddmonkey

Si vous activez la valeur d'une variable unique, j'utiliserais un commutateur à chaque fois.

Sinon, restez avec plusieurs déclarations if-else.

43
Garry Shutler

concernant la lisibilité:

Je préfère généralement si/else construit par-dessus les instructions switch, en particulier dans les langages qui permettent des cas d'échec. Ce que j’ai constaté, c’est souvent que, à mesure que les projets prennent de l’âge et que de nombreux développeurs s’impliquent, vous allez commencer à avoir des problèmes avec la construction d’une instruction switch. 

S'ils (les déclarations) deviennent plus que simples, de nombreux programmeurs deviennent paresseux et au lieu de lire l'intégralité de la déclaration pour la comprendre, ils apparaîtront simplement dans un cas pour couvrir le cas qu'ils ajoutent à la déclaration. 

J'ai vu de nombreux cas où le code se répète dans une instruction de commutateur parce que le test d'une personne était déjà couvert; un simple cas de chute aurait suffi, mais la paresse les a forcés à ajouter le code redondant à la fin au lieu d'essayer de comprendre le commutateur. . J'ai également vu des déclarations de substitution cauchemardesques avec de nombreux cas mal construits, et essayant simplement de suivre toute la logique, avec de nombreux cas d'échec dispersés, et de nombreux cas qui ne l'étaient pas deviennent difficiles ... quel genre des pistes au premier problème de redondance dont j'ai parlé. 

Théoriquement, le même problème pourrait exister avec les constructions if/else, mais dans la pratique, cela ne semble pas se produire aussi souvent. Peut-être (juste une supposition) les programmeurs sont obligés de lire un peu plus attentivement parce que vous devez comprendre les conditions souvent plus complexes testées dans la construction if/else? Si vous écrivez quelque chose de simple que vous savez que les autres risquent de ne jamais toucher et que vous pouvez bien construire, alors j'imagine que c'est un jeu d'enfant. Dans ce cas, tout ce qui est plus lisible et qui vous convient le mieux est probablement la bonne réponse car vous êtes susceptible de maintenir ce code.

concernant la vitesse:

Les instructions switch fonctionnent souvent plus rapidement que les constructions if-else (mais pas toujours). Comme les valeurs possibles d'une instruction switch sont définies à l'avance, les compilateurs peuvent optimiser les performances en construisant des tables de sauts. Chaque condition ne doit pas être testée comme dans une construction if/else (enfin, jusqu'à ce que vous trouviez la bonne). 

Cependant, ce n'est pas toujours le cas, cependant. Si vous avez un commutateur simple, avec des valeurs possibles comprises entre 1 et 10, ce sera le cas. Plus vous ajoutez de valeurs, plus le nombre de tables de saut est grand et plus le commutateur devient efficace (pas comme si/else, mais moins que l’instruction relativement simple du commutateur) . De plus, si les valeurs sont très variables (par exemple, au lieu de 1 à 10, vous avez 10 valeurs possibles, par exemple 1, 1000, 10000, 100000, etc. à 100000000000), le commutateur est moins efficace que dans le cas plus simple. .

J'espère que cela t'aides.

12
Allen Ratcliff

Personnellement, je préfère voir des instructions switch par rapport à un nombre trop élevé d’esclaves, car elles peuvent être beaucoup plus faciles à lire. Les commutateurs sont également meilleurs en termes de lisibilité pour afficher un état.

Voir aussi le commentaire de cet article concernant pacman ifs .

1
SmacL

La tendance à éviter les trucs, car il faut plus de temps pour taper est une mauvaise chose, essayez de les éliminer. Cela dit, les choses trop verbeuses sont également difficiles à lire. Il est donc important de prendre une petite taille et simple, mais c'est la lisibilité et non la capacité d'écriture qui importe. Les lignes simples concises peuvent souvent être plus difficiles à lire qu’un simple fichier bien agencé de 3 ou 4 lignes.

Utilisez la construction qui décrit le mieux la logique de l’opération.

0
AnthonyWJones

Utilisez switch chaque fois que vous avez plus de 2 conditions pour une seule variable, prenez les jours de la semaine par exemple, si vous avez une action différente pour chaque jour de la semaine, vous devez utiliser un commutateur.

D'autres situations (plusieurs variables ou complexes si clauses vous devriez Ifs, mais il n'y a pas de règle sur où utiliser chacun.

0
Sergio

Cela dépend beaucoup du cas spécifique. De préférence, je pense qu’il est préférable d’utiliser le switch par rapport au if-else s’il existe de nombreux if-elses imbriqués. 

La question est combien coûte beaucoup?

Hier je me posais la même question:

public enum ProgramType {
    NEW, OLD
}

if (progType == OLD) {
    // ...
} else if (progType == NEW) {
    // ...
}

if (progType == OLD) {
    // ...
} else {
    // ...
}

switch (progType) {
case OLD:
    // ...
    break;
case NEW:
    // ...
    break;
default:
    break;
}

Dans ce cas, le 1st if a un second test inutile. Le 2e se sent un peu mal car il cache le NOUVEAU.

J'ai fini par choisir le switch car il se lit mieux.

0
bruno conde

Supposons que vous ayez décidé d'utiliser switch car vous ne travaillez que sur une seule variable pouvant avoir différentes valeurs. Si cela se traduisait par une petite instruction switch (2-3 cas), je dirais que ça va. S'il semble que vous vous retrouverez avec plus, je vous recommanderais plutôt d'utiliser le polymorphisme. Un modèle AbstractFactory peut être utilisé ici pour créer un objet qui effectuera toute action que vous tenteriez d'effectuer dans les commutateurs. La déclaration de commutateur laide sera extraite et vous vous retrouverez avec un code plus propre.

0

J'ai souvent pensé que le fait d'utiliser elseif et de laisser tomber des cas (où la langue le permet) est une odeur de code, sinon une odeur.

Pour ma part, j’ai normalement constaté que les expressions imbriquées (si/alors/autre) s reflètent généralement mieux les choses que les autres options et que, dans les cas mutuellement exclusifs (souvent dans lesquels une combinaison d’attributs prime sur un autre), un cas ou un élément similaire est plus clair lire deux ans plus tard.

Je pense que l’instruction select utilisée par Rexx est un bon exemple de la manière de bien faire "Case" (pas de drop-through) (exemple stupide):

Select
    When (Vehicle ¬= "Car") Then
        Name = "Red Bus"
    When (Colour == "Red") Then
        Name = "Ferrari"
    Otherwise
        Name = "Plain old other car"
    End

Oh, et si l'optimisation n'est pas à la hauteur, procurez-vous un nouveau compilateur ou un nouveau langage ...

0
Brent.Longborough

Les instructions Switch sont beaucoup plus faciles à lire et à gérer, mains libres. Et sont généralement plus rapides et moins sujettes aux erreurs.

0
Eldelshell