web-dev-qa-db-fra.com

Le service doit-il lever une exception ou revenir si aucun élément n'est spécifié pour la suppression

J'ai un morceau de code qui peut être représenté comme:

public class ItemService {

    public void DeleteItems(IEnumerable<Item> items)
    {
        // Save us from possible NullReferenceException below.
        if(items == null)
            return;

        foreach(var item in items)
        {
            // For the purpose of this example, lets say I have to iterate over them.
            // Go to database and delete them.
        }
    }
}

Maintenant, je me demande si c'est la bonne approche ou dois-je lever l'exception. Je peux éviter les exceptions, car retourner serait la même chose que d'itérer sur une collection vide, ce qui signifie qu'aucun code important n'est exécuté de toute façon, mais d'un autre côté, je cache peut-être des problèmes quelque part dans le code, car pourquoi quelqu'un voudrait-il appeler DeleteItems avec le paramètre null? Cela peut indiquer qu'il y a un problème ailleurs dans le code.

C'est un problème que j'ai généralement avec les méthodes dans les services, car la plupart d'entre elles font quelque chose et ne renvoient pas de résultat, donc si quelqu'un transmet des informations invalides, il n'y a rien à faire pour le service, donc il revient.

12
FCin

Ce sont deux questions différentes.

Devriez-vous accepter null? Cela dépend de votre politique générale concernant null dans la base de code. À mon avis, interdire null partout sauf là où cela est explicitement documenté est une très bonne pratique, mais c'est encore mieux de s'en tenir à la convention que votre base de code a déjà.

Devriez-vous accepter la collection vide? À mon avis: OUI, absolument. Il faut beaucoup plus d'efforts pour restreindre tous les appelants à des collections non vides que pour faire ce qui est mathématiquement juste - même si cela surprend certains développeurs qui sont incertains avec le concept de zéro.

58
Kilian Foth

Valeur nulle

Comme l'a déjà dit @KilianFoth, respectez votre politique générale. Si c'est pour traiter null comme un "raccourci" pour une liste vide, faites-le de cette façon.

Si vous n'avez pas de politique cohérente sur les valeurs de null, je recommanderais la suivante:

null doit être réservé pour représenter des situations qui ne peuvent pas être exprimées par le type "normal", par exemple en utilisant null pour représenter "je ne sais pas". Et c'est un bon choix, car tous ceux qui essaient d'utiliser cette valeur sans précaution recevront une exception, ce qui est la bonne chose.

L'utilisation de null comme raccourci pour une liste vide ne se qualifie pas de cette façon, car il existe déjà une représentation parfaite, étant une liste avec zéro élément. Et c'est un mauvais choix technique, car il oblige chaque partie de votre code traitant des listes à vérifier la sténographie valide null.

Liste vide

Pour une méthode DeleteItems(), passer une liste vide signifie en fait ne rien faire. J'autoriserais cela comme argument, sans lever d'exception, mais simplement revenir rapidement.

Bien sûr, l'appelant pourrait d'abord vérifier l'absence d'éléments et ignorer l'appel DeleteItems() dans ce cas. Si nous parlons d'une API Web, pour des raisons d'efficacité, l'appelant devrait le fait pour éviter le trafic inutile et les latences aller-retour. Mais je ne pense pas que votre API devrait appliquer cela.

9
Ralf Kleberhoff

Lancez une exception et gérez les valeurs NULL dans le code appelant.

En règle générale, essayez d'éviter null en tant que valeurs de paramètre. Cela réduira les NullPointerExceptions en général, car les valeurs nulles seront vraiment une exception.

En plus de cela, regardez le reste de votre code. S'il s'agit d'un modèle courant dans votre projet, restez cohérent.

1
serprime

D'une manière générale, la levée d'exceptions doit être réservée à des situations exceptionnelles, c'est-à-dire si le code n'a pas de ligne de conduite raisonnable à prendre dans le contexte actuel.

Vous pouvez appliquer ce processus de réflexion à cette situation. Étant donné qu'il s'agit d'une classe publique avec une méthode publique, vous disposez d'une API publique et, en théorie, aucun contrôle sur ce qui lui est transmis.

Votre code n'a aucun contexte sur ce qui l'appelle (comme il ne devrait pas), et il n'y a rien que vous puissiez raisonnablement faire avec une valeur nulle. Ce serait certainement un candidat pour un ArgumentNullException.

0
richzilla

Cette question ne semble pas concerner les exceptions, mais plutôt que null est un argument valide.

Donc, vous devez d'abord et avant tout décider si null est une valeur autorisée pour votre argument de cette méthode. Si c'est le cas, vous n'avez pas besoin d'une exception. Si ce n'est pas le cas, vous avez besoin d'une exception.

Que vous souhaitiez autoriser null, ou non, est discutable, comme en témoignent de nombreux hits Google à ce sujet. Cela signifie que vous n'obtiendrez pas de réponse claire et que cela dépend quelque peu de l'opinion et de la tradition de l'endroit où vous travaillez.

Un autre point litigieux est de savoir si une fonction de bibliothèque doit être vraiment stricte à ce sujet, ou aussi indulgente que possible, tant qu'elle n'essaie pas de "corriger" des paramètres erronés. Comparez cela au monde des protocoles réseau, du transfert de courrier, etc. (qui sont des contrats d'interface, tout comme les méthodes de programmation). Là, généralement, la politique est que l'expéditeur doit se conformer aussi strictement que possible au protocole, tandis que le récepteur doit se mettre en quatre pour pouvoir travailler avec tout ce qui se présente.

Vous devez donc décider: est-ce vraiment le travail d'une méthode de bibliothèque d'appliquer une politique assez large comme la gestion de null? Surtout si votre bibliothèque est également utilisée par d'autres personnes (qui peuvent avoir des politiques différentes).

Je me tromperais probablement du côté d'autoriser les valeurs de null, de définir et de documenter leur sémantique (c'est-à-dire null = empty array dans ce cas), et ne lève pas d'exception, sauf 99% de votre autre code similaire (code de style "bibliothèque") fait l'inverse.

0
AnoE