web-dev-qa-db-fra.com

Utilisation de l'opérateur NOT dans des conditions IF

Est-ce vraiment une bonne pratique d'éviter d'utiliser l'opérateur NOT dans les conditions IF afin de rendre votre code plus lisible? J'ai entendu dire que if (doSomething()) est meilleur que if (!doSomething()).

25
Eugene

Cela dépend vraiment de ce que vous essayez d'accomplir. Si vous n'avez pas d'autre clause, alors if(!doSomething()) vous convient. Cependant, si vous avez

if(!doSomething()) {
    ...
}
else {
    // do something else
}

J'inverserais probablement cette logique pour supprimer l'opérateur ! et rendre la clause if légèrement plus claire.

39
Bill the Lizard

En règle générale, il est bon de rendre vos conditions conditionnelles aussi lisibles que possible. Pour votre exemple, utilisez! est ok le problème est quand les choses ressemblent

if ((a.b && c.d.e) || !f)

vous voudrez peut-être faire quelque chose comme

bool isOk = a.b;
bool isStillOk = c.d.e
bool alternateOk = !f

alors votre déclaration si est simplifiée à

if ( (isOk && isStillOk) || alternateOk)

Cela rend le code plus lisible. Et si vous devez déboguer, vous pouvez déboguer l'ensemble de vars isOk au lieu d'avoir à creuser à travers les variables de la portée. Il est également utile de traiter les NPE: il est toujours bon de décomposer le code en morceaux plus simples.

19
hvgotcodes

Non, l'utilisation de l'opérateur ! dans les instructions if..then..else ne présente absolument aucun inconvénient.

La dénomination des variables, et dans votre exemple, des méthodes est ce qui est important. Si vous utilisez:

if(!isPerson()) { ... } // Nothing wrong with this

Toutefois:

if(!balloons()) { ... } // method is named badly

Tout se résume à la lisibilité. Visez toujours ce qui est le plus lisible et vous ne vous tromperez pas. Essayez toujours de garder votre code continu également, par exemple, regardez Bill the Lizards answer .

11
Kyle Rozendo

En général, ! est un opérateur logique booléen parfaitement bon et lisible. Aucune raison de ne pas l'utiliser sauf si vous simplifiez l'application en supprimant les doubles négations ou en appliquant la loi de Morgan.

!(!A) = A

ou

!(!A | !B) = A & B

En règle générale, conservez la signature de vos méthodes de retour booléen mnémonique et conforme à la convention. Le problème avec le scénario proposé par @hvgotcodes est que, bien entendu, a.b et c.d.e ne sont pas des exemples très conviviaux. Supposons que vous ayez une classe de vol et une classe de siège pour une application de réservation de vol. Alors la condition pour réserver un vol pourrait parfaitement être quelque chose comme

if(flight.isActive() && !seat.isTaken())
{
    //book the seat
}

Ce code parfaitement lisible et compréhensible. Vous pouvez redéfinir votre logique booléenne pour la classe Seat et reformuler la condition en conséquence.

if(flight.isActive() && seat.isVacant())
{
    //book the seat
}

Supprimant ainsi le! opérateur si cela vous dérange vraiment, mais vous verrez que tout dépend de la signification de vos méthodes booléennes.

4
Mig82

essayez comme ça

if (!(a | b)) {
    //blahblah
}

C'est pareil avec

if (a | b) {}
else {
    // blahblah
}
1
Jae Lee

Ce n’est généralement pas une mauvaise idée d’éviter l’opérateur! Si vous avez le choix. Une raison simple est que cela peut être une source d’erreurs car il est possible de l’ignorer. Plus lisible peut être: if (conditionA == false) dans certains cas. Cela joue principalement un rôle si vous sautez la partie else. Si vous avez de toute façon un bloc else, vous ne devriez pas utiliser la négation dans la condition if. 

Sauf pour les conditions composées comme ceci:

if(!isA() && isB() && !isNotC())

Ici, vous devez utiliser une sorte de négation pour obtenir la logique désirée . Dans ce cas, ce qui mérite vraiment de penser est de nommer les fonctions ou les variables . Essayez de les nommer de sorte que vous puissiez souvent les utiliser dans des conditions simples sans négation.

Dans ce cas, réfléchissez à la logique de isNotC () et si elle pourrait être remplacée par une méthode isC () si cela a du sens.

Enfin, votre exemple présente un autre problème de lisibilité, qui est encore plus grave que la question de savoir si la négation doit être utilisée ou non: le lecteur du code sait-il vraiment quand doSomething () renvoie vrai et quand faux? faux a-t-il été fait quand même? Il s’agit d’un problème très courant, qui amène le lecteur à essayer de comprendre ce que signifient réellement les valeurs de retour des fonctions.

1
FabianB

Je n'ai jamais entendu parler de celui-ci avant.

Comment est 

if (doSomething()) {
} else {
   // blah
}

mieux que

if (!doSomething()) {
   // blah
}

Ce dernier est plus clair et concis.

Outre le! opérateur peut apparaître dans des conditions complexes telles que (! a || b). Comment l'évitez-vous alors?

Utilisez le ! opérateur quand vous avez besoin.

0
Alexandru