Je suis un peu en désaccord avec un développeur plus expérimenté sur cette question et je me demande ce que les autres en pensent; notre environnement est Java, EJB 3, services, etc.
Le code que j'ai écrit appelle un service pour obtenir des choses et pour créer des choses. Le problème que j'ai rencontré est que j'ai obtenu des exceptions de pointeur nul qui n'avaient aucun sens. Par exemple, lorsque je demande au service de créer un objet, je récupère null; lorsque j'essaie de rechercher un objet avec un ID valide connu, j'obtiens null back. J'ai passé quelque temps à essayer de comprendre ce qui n'allait pas dans mon code; comme je suis moins expérimenté, je suppose généralement que j'ai fait quelque chose de mal, mais il s'avère que la raison des retours nuls était la sécurité. Si l'utilisateur principal utilisant mon service n'avait pas les bonnes autorisations pour le service cible, il renvoie simplement null. La plupart des autres services ici ne sont pas non plus très bien documentés, donc apparemment, c'est juste quelque chose que vous devez savoir.
C'est assez déroutant pour un développeur qui écrit du code qui interagit avec le service. Cela aurait beaucoup plus de sens pour moi si le service contenait une exception qui me dirait que l'utilisateur n'avait pas les autorisations appropriées pour charger cette chose ou pour créer cette chose; Je saurais alors immédiatement pourquoi mon service ne fonctionnait pas comme prévu.
Le développeur le plus expérimenté qui a écrit le service a fait valoir que demander les données n'est pas une condition d'erreur et que les exceptions ne devraient être levées que dans une condition d'erreur, pas lorsque l'utilisateur n'a pas accès aux données. Ces données sont souvent recherchées dans une interface graphique, et pour les utilisateurs sans les bonnes autorisations, ces choses «n'existent tout simplement pas». Donc, en bref: demander n'est pas faux, donc pas d'exception. Les méthodes get renvoient null car pour ces utilisateurs ces choses «n'existent pas». Les méthodes de création renvoient null lorsque l'utilisateur n'était pas autorisé à créer cette chose.
Est-ce une pratique normale et / ou bonne? Je préfère utiliser les exceptions parce que je trouve beaucoup plus facile de savoir ce qui se passe. Donc, je préfère par exemple également lancer une NotFoundException si vous avez demandé un objet avec un ID non valide, plutôt que de retourner null.
la source
Réponses:
Demander une chose n'est peut-être pas une erreur, mais ne pas avoir l'autorisation de quelque chose que vous avez demandé est sûrement une sorte d'erreur. Les exceptions sont un autre moyen de signaler des conditions exceptionnelles, à utiliser à la place de valeurs de retour spéciales (comme
null
, qui, comme vous l'avez écrit, ne sont d'aucune utilité s'il y a> 1 raisons possibles pour lesquelles les choses pourraient mal tourner (même s'il y a exactement 1 raison possible maintenant, il pourrait y avoir 2 raisons possibles dans la prochaine version, donc utilisernull
comme valeur de retour indiquant l'échec serait vous peindre dans le coin)). Si le service ne rapporte en aucune façon pourquoi il ne fera pas ce que vous avez demandé, alors c'est définitivement une mauvaise conception.L'utilisation ou non d'une valeur de retour spéciale (par exemple, les entiers négatifs sont utiles pour les fonctions qui renvoient normalement un entier non négatif), une exception, un gestionnaire d'erreurs global ou un enregistreur, etc., est un détail d'implémentation à la fin. Le choix dépend de la langue, de la situation, des conventions, et c'est aussi une question de goût. Le point principal est qu'il devrait y avoir une façon directe de savoir pourquoi quelque chose ne fonctionne pas. Sinon, votre seule option est de jeter les ordures avec différentes options et autres pour savoir ce qui est en corrélation avec le comportement de la boîte noire, et c'est une perte de temps.
String.substring()
jette unIndexOutOfBoundsException
si l'index est hors limites. Je ne peux penser à aucun avantage à retourner à lanull
place, même si - philosophiquement - on pourrait dire que aString
ne contient rien en dehors de ses limites, cenull
serait donc une valeur de retour logique. Être logico-philosophique et être pratique sont évidemment deux animaux différents.la source
substring
retourner une référence nulle. À mon humble avis, il devrait y avoir deux fonctions distinctes - dont l'une promet de renvoyer le nombre de caractères demandé ou de lever une exception, et dont l'une renvoie autant que possible. Chaque méthode serait sensiblement supérieure à l'autre dans certains contextes.Cela revient à ce qu'est le contrat. Si votre contrat stipule que vous pouvez demander quelque chose qui n'existe pas, il doit indiquer ce qui se passe (null ou objet null).
D'un autre côté, si votre contrat stipule que vous devez d'abord appeler une méthode différente (
DoesSomethingExist()
) puis laGet
méthode, votre contrat peut dire que vous ne pouvez obtenir que les choses qui existent et lever une exception si elles ne le font pas. Le message d'exception pourrait dire quelque chose comme «Assurez-vous d'appeler enDoesSomethingExist()
premier», qui est un message d'erreur utile.la source
findAllThings
méthode, je dirais qu'il convient de renvoyer une liste vide ou un sous-ensemble s'il y a certaines ou toutes les choses que vous n'êtes pas autorisé à voir. De la même manière, je pourrais sur un blog ne lister que les articles à éditer appartenant à l'utilisateur actuel. Mais si cet utilisateur a ensuite essayé de modifier l'URL et de modifier un message différent ...Il n'y a pas de réponse unique à la question. Que ce soit pour utiliser des exceptions ou retourner null dépend de la situation.
Au lieu de regarder cela purement d'un point de vue dogmatique, regardez l'interface comme une interface utilisateur . Les interfaces utilisateur doivent être utilisables . Donc, indépendamment de vos propres opinions sur la "bonne" façon de faire quelque chose, choisissez la méthode la plus utilisable du point de vue de quelqu'un qui utilise votre interface.
Si l'appelant a besoin de savoir pourquoi un objet n'est pas retourné, une exception est appropriée. Si, cependant, le concept général est "si vous n'avez pas d'autorisation, cela n'existe pas", la valeur null est acceptable.
Plus précisément dans votre cas, je dirais que les valeurs nulles sont parfaitement acceptables pour rechercher un élément si l'appelant doit d'abord se connecter ou se connecter au serveur. C'est à ce moment qu'on vous dirait que vous avez ou non la permission. Une fois que vous avez franchi la porte, il est raisonnable que lorsque vous recherchez quelque chose que vous n'avez pas la permission de voir (ou même que vous savez qu'il existe), vous devriez obtenir un null.
Si, en revanche, vous n'avez pas de connexion initiale ou d'étape de connexion, une exception est logique. Si l'appelant sait qu'un élément existe et qu'il ne le récupère pas, l'API n'est pas utile pour renvoyer simplement une valeur nulle.
Pour créer un élément, cependant, c'est une autre histoire. Vraisemblablement, il pourrait y avoir de nombreuses raisons à cela - pas d'autorisations, de mauvais paramètres, une mémoire insuffisante du serveur, etc. .
Donc, pour répondre à la question, demandez-vous quelle est la solution la plus utilisable du point de vue d'une personne utilisant le service. Il se peut que la façon dont vous l' utilisez soit atypique, et dans le cas le plus courant, une valeur nulle est la bonne réponse.
Alors, ne vous lancez pas dans une guerre religieuse à ce sujet, décidez ce qui convient à ce problème particulier.
la source
Je pense vraiment que c'est une mauvaise conception . Null-pointer n'est pas une réponse valable pour moi et cela peut être difficile à gérer.
Si l'utilisateur essaie de se connecter à un service sans les informations d'identification appropriées, je dois répondre avec une réponse claire et concise. La réponse pourrait être une exception ou un objet spécial mais pas null.
Vous devez laisser la réponse nulle lorsque la liaison réseau est rompue ou tout autre dysfonctionnement critique inattendu.
De plus, le temps que vous passez à comprendre pourquoi vous avez obtenu un nul est un argument fort. Tout morceau de code doit être facile à comprendre et à utiliser. Avoir une valeur nulle n'est pas le cas.
la source
En gardant à l'esprit une bonne conception logicielle, vous devez penser à la durée de vie de votre projet.
En rentrant
null
, comme cela a été dit, vous ne donnez aucune information au client. Regardez ce qui vous est arrivé, au début vous ne saviez pas où était le problème. De plus, si aucune documentation n'est fournie, c'est un gâchis.En lançant une exception, vous pouvez dire ce qui s'est mal passé. Vous pouvez même personnaliser le texte affiché pour être plus spécifique si vous le souhaitez.
D'un autre côté, en revenant,
null
vous incitez le client à enquêter sur ce qui se passe.De plus, vous avez réalisé qu'il y avait un problème parce que vous êtes allé ailleurs a
NullPointerException
. Imaginez maintenant que vous ne stockiez pas le retour de cette fonction ... Vous serez obligé d'entourer chaque appel de cette fonction d'unif else
bloc ...De mon point de vue, le retour
null
est une mauvaise pratique.la source
De mon point de vue, cela n'a aucun sens.
L'interrogation de données sans autorisation doit entraîner une exception, car il s'agit d'un résultat inattendu - pour obtenir aucun résultat - sans accès approprié.
Analogie : Le responsecode pour un
GET
sans autorisation n'est pas200 ok
sans données, c'est en fait401 Unauthorized
.la source
Renvoyer null n'est pas génial. Ça ne vous dit rien. Pour prendre votre exemple, si une application essaie de rechercher quelque chose et que la réponse est nulle pour les deux problèmes de sécurité et si l'élément n'existe pas, comment pouvez-vous faire la différence entre les deux?
Une réponse significative peut permettre à l'application de faire des choix logiques sur ce qu'il faut faire ensuite ou comment résoudre les problèmes.
la source
Si la cause principale est un utilisateur non authentifié, je préfère une réponse HTTP 401 dure, peut-être avec une redirection vers une jolie page de message (et une notification à quelqu'un qui s'en soucie). Les causes liées à l'autorisation sont plus au cas par cas; il existe des arguments pour renvoyer des erreurs HTTP (403, par exemple) et des arguments pour renvoyer des codes / messages spéciaux bien formés dans la réponse du service.
Les exceptions ne doivent être utilisées que dans des circonstances exceptionnelles et signifient que quelque chose s'est mal passé. Je ne suis pas d'accord pour dire qu'ils devraient être surchargés pour signifier "non autorisés". (La même chose est vraie pour la valeur de retour nulle: je ne suis pas d'accord qu'elle devrait être utilisée pour signifier "non autorisé".)
la source
Pour jouer l'avocat des démons, j'essaierai de prendre le parti du retour nul.
À mon avis, il n'y a qu'une seule situation où ce type de réponse est presque acceptable et c'est, comme dans ce cas, la sécurité.
Il est très facile de divulguer accidentellement des détails de votre système que les personnes non autorisées ne devraient pas connaître. Cela devrait être évité.
Prenons, par exemple, un vérificateur de nom d'utilisateur et de mot de passe. Le renvoi d'une erreur "Nom d'utilisateur introuvable" et d'une erreur "Mot de passe incorrect" en tant que codes d'erreur distincts vous ouvrirait évidemment à de graves problèmes de sécurité car quelqu'un pourrait d'abord rechercher un nom d'utilisateur valide, puis rechercher un mot de passe. Renvoyer un "nom d'utilisateur / mot de passe invalide" générique serait une meilleure option.
Ainsi, dans ce cas particulier, je dirais qu'il est presque correct de revenir
null
mais je suis d'accord, ce serait très désagréable de travailler avec.la source
null
est exactement la réponse la moins utile. Presque tout le reste pourrait potentiellement être utilisé pour découvrir quelque chose sur le système. OP s'est plainte parce que non seulement lenull
retour n'expliquait rien, mais qu'il était même inutile. Tel est le but délibéré ... de ne rien dire et de ne pas aider. Mission accomplie à mon avis.Je pense que return null est hostile, lorsque le client invoque cette méthode et retourne null, le client ne sait pas ce qui s'est passé et pourquoi il a renvoyé null. Nous devrions donc lancer une exception qui est logique et fournir une documentation pour décrire cette exécution.
la source