Le retour d'une mauvaise conception est-il nul? [fermé]

127

J'ai entendu des voix dire que vérifier une valeur nulle renvoyée par les méthodes est une mauvaise conception. J'aimerais entendre quelques raisons à cela.

pseudocode:

variable x = object.method()
if (x is null) do something
Koen
la source
13
Élaborez: où sont ces gens qui disent que c'est mauvais? Liens?
jcollum
2
Si la méthode est quelque chose que vous contrôlez, vous pouvez avoir des tests unitaires pour vous assurer qu'elle ne retourne jamais null, sinon, je ne vois pas pourquoi ce serait une mauvaise pratique de vérifier si elle est nulle après cet appel; c'est peut-être une mauvaise pratique sur cette méthode de retourner null, mais vous devez protéger votre code
BlackTigerX
9
Lever des exceptions simplement parce qu'il n'y a pas de données à renvoyer est incroyablement ennuyeux. Le flux de programme normal ne doit pas lever d'exceptions.
Thorarin
4
@David: C'est vraiment ce que j'ai dit. Si une méthode doit renvoyer des données, mais qu'il n'y en a pas, cela signifie que quelque chose s'est également mal passé. Ce n'est pas le déroulement normal du programme :)
Thorarin
2
@Thorarin: le flux de programme "normal" est un concept assez extensible: pas vraiment une base solide pour un argument.
Tomislav Nakic-Alfirevic

Réponses:

206

La justification de ne pas renvoyer null est que vous n'avez pas à le vérifier et que votre code n'a donc pas besoin de suivre un chemin différent en fonction de la valeur de retour. Vous voudrez peut-être consulter le modèle d'objet nul qui fournit plus d'informations à ce sujet.

Par exemple, si je devais définir une méthode en Java qui retournait une collection, je préférerais généralement renvoyer une collection vide (c'est-à-dire Collections.emptyList()) plutôt que null car cela signifie que mon code client est plus propre; par exemple

Collection<? extends Item> c = getItems(); // Will never return null.

for (Item item : c) { // Will not enter the loop if c is empty.
  // Process item.
}

... qui est plus propre que:

Collection<? extends Item> c = getItems(); // Could potentially return null.

// Two possible code paths now so harder to test.
if (c != null) {
  for (Item item : c) {
    // Process item.
  }
}
Adamski
la source
6
Oui, bien mieux que de renvoyer null et d'espérer que le client se souviendra de traiter le cas.
djna
10
Je conviendrai volontiers que retourner null est insensé lorsqu'il est utilisé comme substitut à des conteneurs vides (ou des chaînes). Ce n'est cependant pas le cas courant.
MSalters
2
+1 pour le modèle d'objet nul pour moi aussi. Aussi, quand je veux vraiment retourner null, j'ai nommé la méthode comme getCustomerOrNull () pour la rendre explicite. Je pense qu'une méthode est bien nommée lorsque le lecteur ne veut pas regarder l'implémentation.
Mike Valenty
4
Le commentaire «// Deux chemins de code possibles maintenant» n'est pas correct; vous avez deux chemins de code dans les deux sens. Cependant, avec l'objet Collection null dans votre premier exemple, le chemin du code «null» est plus court. Cependant, vous avez toujours deux chemins et vous devez encore tester deux chemins.
Frerich Raabe
1
@MSalters - sans doute chaque variable dans les langages OO avec nullest un "conteneur", qui contient zéro ou un pointeur vers des objets. (C'est certainement ainsi qu'il est explicitement modélisé par Haskell Maybedans ces cas, et c'est d'autant mieux pour le faire.)
Andrzej Doyle
71

Voici la raison.

Dans Clean Code de Robert Martin, il écrit que renvoyer null est une mauvaise conception lorsque vous pouvez à la place retourner, disons, un tableau vide. Puisque le résultat attendu est un tableau, pourquoi pas? Cela vous permettra de parcourir le résultat sans aucune condition supplémentaire. Si c'est un entier, peut-être que 0 suffira, si c'est un hachage, un hachage vide. etc.

Le principe est de ne pas forcer le code d'appel à traiter immédiatement les problèmes. Le code d'appel peut ne pas vouloir se préoccuper d'eux. C'est aussi pourquoi, dans de nombreux cas, les exceptions valent mieux que nul.

Max Chernyak
la source
2
Voici le modèle d'objet nul mentionné dans cette réponse: stackoverflow.com/questions/1274792/…
Scott Dorman
L'idée ici est qu'en cas d'erreur, vous retournez une version vide / vide du type d'objet que vous renverriez normalement. Un tableau ou une chaîne vide fonctionnerait pour ces cas, par exemple. Renvoyer "NULL" est approprié lorsque vous retournez normalement un pointeur (puisque NULL est essentiellement un pointeur vide). Renvoyer NULL en cas d'erreur à partir d'une fonction qui renvoie normalement, disons, un hachage peut être déroutant. Certaines langues gèrent cela mieux que d'autres, mais en général, la cohérence est la meilleure pratique.
bta le
Vous ne retournez pas nécessairement en cas d'erreur, à moins que l'erreur ne contrôle d'une manière ou d'une autre le flux (ce qui n'est pas une bonne pratique) ou est abstraite dans l'API ou l'interface. Les erreurs sont là pour se propager à n'importe quel niveau auquel vous décidez de l'attraper, vous n'avez donc pas à les gérer dans le contexte d'appel. Ils sont par défaut compatibles avec les modèles d'objet nul.
Max Chernyak
Malheureusement, le code d'appel ne considère pas toujours le cas d'une collection vide (tout comme il ne considère pas le cas nul). Cela peut ou non être un problème.
Sridhar Sarnobat
38

Bonnes utilisations du retour de null:

  • Si null est un résultat fonctionnel valide , par exemple: FindFirstObjectThatNeedsProcessing () peut retourner null s'il n'est pas trouvé et l'appelant doit vérifier en conséquence.

Mauvaises utilisations: essayer de remplacer ou de masquer des situations exceptionnelles telles que:

  • catch (...) et retourne null
  • L'initialisation de la dépendance API a échoué
  • Espace disque insuffisant
  • Paramètres d'entrée non valides (erreur de programmation, les entrées doivent être nettoyées par l'appelant)
  • etc

Dans ces cas, lever une exception est plus adéquat car:

  • Une valeur de retour nulle ne fournit aucune information d'erreur significative
  • L'appelant immédiat ne peut probablement pas gérer la condition d'erreur
  • Il n'y a aucune garantie que l'appelant recherche des résultats nuls

Cependant, les exceptions ne doivent pas être utilisées pour gérer les conditions normales de fonctionnement du programme telles que:

  • Nom d'utilisateur / mot de passe invalide (ou toute entrée fournie par l'utilisateur)
  • Rupture de boucles ou comme gotos non locaux
ZeroConcept
la source
7
"Nom d'utilisateur invalide" semble cependant être une bonne cause d'exception.
Thilo
11
Les utilisateurs qui saisissent des identifiants / mots de passe invalides ne doivent pas être traités comme des conditions exceptionnelles, faisant partie du fonctionnement normal du programme. Cependant, l'échec du système d'authentification (par exemple, Active Directory) est une condition exceptionnelle.
ZeroConcept
2
Je dirais que cela dépend: boolean login(String,String)semble bien et aussiAuthenticationContext createAuthContext(String,String) throws AuthenticationException
sfussenegger
1
Dans votre exemple, s'il n'y a pas de premier objet à traiter, il existe deux manières raisonnables de traiter ce cas. Le premier est le modèle d'objet nul. Créez une sous-classe finale qui représente une version inexistante de la classe. Il a des valeurs par défaut raisonnables et lève des exceptions lorsque des actions absurdes sont demandées. L'autre technique est l'option. C'est ce qui est disponible en Java8 et Scala. L'un ou l'autre montre l'intention des développeurs. null ne peut pas afficher l'intention car il a trop de significations possibles. ** Montrer l'intention ** est l'aspect le plus important du code.
scott m gardner
29

Oui, renvoyer NULL est une conception terrible , dans un monde orienté objet. En un mot, l'utilisation NULL conduit à:

  • gestion des erreurs ad hoc (au lieu d'exceptions)
  • sémantique ambiguë
  • lent au lieu d'échouer rapidement
  • la pensée informatique au lieu de la pensée objet
  • objets mutables et incomplets

Consultez ce billet de blog pour une explication détaillée: http://www.yegor256.com/2014/05/13/why-null-is-bad.html . Plus dans mon livre Objets élégants , section 4.1.

yegor256
la source
2
Je suis tout à fait d’accord. Je n'aime même pas le motif d'objet nul qui semble être une tactique de retard de «blanchiment». Soit votre méthode est supposée réussir toujours, soit elle peut ne pas l'être. Si cela réussit toujours, lancez-le. Si cela ne réussit pas, concevez la méthode pour que le consommateur sache, par exemple bool TryGetBlah(out blah)ou FirstOrNull()ou MatchOrFallback(T fallbackValue).
Luke Puplett
Moi aussi, je n'aime pas retourner null. Vous séparez la cause première du symptôme, ce qui rend le débogage plus difficile. Soit lancer une exception (échec rapide), soit appeler une méthode checker qui retourne d'abord un booléen (par exemple isEmpty()) et seulement si c'est vrai alors appelez la méthode. Les gens s'opposent à la deuxième affirmant que ses performances sont moins bonnes - mais comme le dit la philosophie Unix, «valorise le temps humain par rapport au temps machine» (c'est-à-dire que des performances trivialement plus lentes perdent moins de temps que les développeurs déboguant du code qui donne des erreurs fallacieuses).
Sridhar Sarnobat
22

Qui a dit que c'était une mauvaise conception?

La vérification des valeurs nulles est une pratique courante, même encouragée, sinon vous courez le risque de NullReferenceExceptions partout. Il est préférable de gérer l'erreur avec élégance plutôt que de lever des exceptions lorsque vous n'en avez pas besoin.

Brandon
la source
11
+1. Le code qui jette des exceptions pour les problèmes qui peuvent être atténués sur place me rend triste.
jkeys
6
À quel point êtes-vous triste lorsque les codeurs oublient de vérifier les valeurs nulles, puis obtiennent de mystérieuses exceptions de pointeur nul? Les exceptions vérifiées, où le compilateur rappelle à l'utilisateur qu'il n'a pas traité les conditions d'erreur, évitent la classe d'erreurs de codage.
djna
3
@djna: Je suppose que c'est également triste, mais j'ai trouvé que le même type de codeurs qui "oublient" de vérifier les valeurs nulles sont ceux qui, lorsqu'ils traitent des exceptions vérifiées, finissent souvent par les avaler.
Randy soutient Monica
5
Il est plus facile de repérer la présence d'un bloc catch vide que l'absence d'un contrôle nul.
Preston
20
@Preston: Je ne suis pas du tout d'accord. Absence de contrôle nul que vous remarquerez immédiatement, quand il plante. Les exceptions avalées peuvent propager des erreurs mystérieuses et subtiles pendant des années ...
Beska
18

D'après ce que vous avez dit jusqu'à présent, je pense qu'il n'y a pas suffisamment d'informations.

Renvoyer null depuis une méthode CreateWidget () semble mauvais.

Renvoyer null depuis une méthode FindFooInBar () semble correct.

jcollum
la source
4
Similaire à ma convention: requêtes d'élément unique - Create... retourne une nouvelle instance, ou lance ; Get...renvoie une instance existante attendue, ou jette ; GetOrCreate...renvoie une instance existante, ou une nouvelle instance s'il n'y en a pas, ou renvoie ; Find...renvoie une instance existante, si elle existe, ounull . Pour les requêtes de collection - Get... renvoie toujours une collection, qui est vide si aucun élément correspondant n'est trouvé.
Johann Gerell
NULL est mauvais pour les raisons données dans la réponse de yegor256 et hakuinin, renvoyer un objet valide mais vide simplifie le raisonnement
global
12

Son inventeur dit que c'est une erreur d'un milliard de dollars!

Bahadır Yağan
la source
10

Cela dépend de la langue que vous utilisez. Si vous êtes dans un langage comme C # où la manière idiomatique d'indiquer l'absence de valeur est de retourner null, alors renvoyer null est une bonne conception si vous n'avez pas de valeur. Alternativement, dans des langages tels que Haskell qui utilisent idiomatiquement la monade Maybe dans ce cas, alors retourner null serait une mauvaise conception (si c'était même possible).

Greg Beech
la source
2
+1 pour avoir mentionné peut-être monade. Je trouve que la définition de nulldans des langages tels que C # et Java est souvent surchargée et donne un sens dans le domaine. Si vous recherchez le nullmot - clé dans les spécifications de langue, cela signifie simplement "un pointeur non valide". Cela ne signifie probablement rien dans aucun domaine problématique.
MattDavey
Le problème est que vous ne savez pas si c'est une "valeur manquante" nullou "non initialisée"null
CervEd
5

Si vous lisez toutes les réponses, il devient clair que la réponse à cette question dépend du type de méthode.

Premièrement, lorsque quelque chose d'exceptionnel se produit (IOproblem, etc.), des exceptions sont logiquement levées. Quand exactement quelque chose est exceptionnel, c'est probablement quelque chose pour un sujet différent.

Chaque fois qu'une méthode ne devrait pas donner de résultats, il existe deux catégories:

  • S'il est possible de renvoyer une valeur neutre, faites-le .
    Les énumérables vides, les chaînes, etc. sont de bons exemples
  • Si une telle valeur neutre n'existe pas, null doit être renvoyé .
    Comme mentionné, la méthode est supposée ne pas avoir de résultat, elle n'est donc pas exceptionnelle et ne doit donc pas lever d'exception. Une valeur neutre n'est pas possible (par exemple: 0 n'est pas spécialement un résultat neutre, selon le programme)

Jusqu'à ce que nous ayons un moyen officiel de désigner qu'une fonction peut ou ne peut pas retourner null, j'essaie d'avoir une convention de dénomination pour le désigner.
Tout comme vous avez la convention Try Something () pour les méthodes qui devraient échouer, je nomme souvent mes méthodes Safe Something () lorsque la méthode renvoie un résultat neutre au lieu de null.

Je ne suis pas encore tout à fait d'accord avec le nom, mais je ne pourrais rien trouver de mieux. Donc je cours avec ça pour le moment.

Boris Callens
la source
4

J'ai une convention dans ce domaine qui m'a bien servi

Pour les requêtes sur un seul élément:

  • Create...renvoie une nouvelle instance ou lance
  • Get...renvoie une instance existante attendue, ou lance
  • GetOrCreate...renvoie une instance existante, ou une nouvelle instance s'il n'y en a pas, ou renvoie
  • Find...renvoie une instance existante, si elle existe, ounull

Pour les requêtes de collection:

  • Get... renvoie toujours une collection, qui est vide si aucun élément [1] correspondant n'est trouvé

[1] étant donné certains critères, explicites ou implicites, donnés dans le nom de la fonction ou en paramètres.

Johann Gerell
la source
Pourquoi GetOne et FindOne retournent-ils différemment s'ils ne sont pas trouvés?
Vladimir Vukanac
J'ai décrit la différence. J'utilise Getquand je m'attends à ce qu'il soit là, de sorte que s'il n'y est pas, alors c'est une erreur et je lance - je n'ai jamais besoin de vérifier la valeur de retour. J'utilise Findsi je ne sais vraiment pas si c'est là ou non - alors je dois vérifier la valeur de retour.
Johann Gerell
3

Les exceptions concernent des circonstances exceptionnelles .

Si votre fonction est destinée à trouver un attribut associé à un objet donné et que cet objet n'a pas d'attribut de ce type, il peut être approprié de renvoyer null. Si l'objet n'existe pas, lever une exception peut être plus approprié. Si la fonction est censée renvoyer une liste d'attributs et qu'il n'y en a aucun à renvoyer, renvoyer une liste vide a du sens - vous renvoyez tous les attributs nuls.


la source
1
Si vous essayez d' utiliser un attribut sans valeur, cela mérite une exception. (Je suppose que votre spécification dit que l'attribut est facultatif.) Ayez une méthode distincte pour vérifier si sa valeur a été définie.
Preston
3

C'est bien de retourner null si cela est significatif d'une certaine manière:

public String getEmployeeName(int id){ ..}

Dans un cas comme celui-ci, il est significatif de renvoyer null si l'ID ne correspond pas à une entité existante, car cela vous permet de distinguer le cas où aucune correspondance n'a été trouvée d'une erreur légitime.

Les gens peuvent penser que c'est mauvais parce qu'il peut être abusé en tant que valeur de retour "spéciale" qui indique une condition d'erreur, ce qui n'est pas si bon, un peu comme renvoyer des codes d'erreur à partir d'une fonction mais déroutant car l'utilisateur doit vérifier le retour pour null, au lieu d'attraper les exceptions appropriées, par exemple

public Integer getId(...){
   try{ ... ; return id; }
   catch(Exception e){ return null;}
}
Steve B.
la source
3
Ouaip. Si vous avez une condition d'erreur, lancez une exception.
David Thornley
3
C'est un cas où une exception serait justifiée. Si vous demandez le nom d'un employé qui n'existe pas, quelque chose ne va évidemment pas.
Thorarin
Je pense que c'est un peu littéral, Thorarin-vous pouvez ergoter avec mon exemple, certes, mais je suis sûr que vous pouvez imaginer une instance d'une fonction qui renvoie une valeur correspondante, ou null s'il n'y a pas de correspondance. Que diriez-vous d'obtenir une valeur à partir d'une clé dans une table de hachage? (J'aurais dû penser à cet exemple en premier lieu).
Steve B.
1
Une table de hachage retournant null pour une clé qui n'existe pas est mauvaise. Cela signifie automatiquement que vous ne pouvez pas stocker null en tant que valeur sans code incohérent.
RHSeeger
3

Ce n'est pas nécessairement une mauvaise conception - comme pour beaucoup de décisions de conception, cela dépend.

Si le résultat de la méthode est quelque chose qui n'aurait pas un bon résultat en utilisation normale, renvoyer null est très bien:

object x = GetObjectFromCache();   // return null if it's not in the cache

S'il doit toujours y avoir un résultat non nul, il peut être préférable de lever une exception:

try {
   Controller c = GetController();    // the controller object is central to 
                                      //   the application. If we don't get one, 
                                      //   we're fubar

   // it's likely that it's OK to not have the try/catch since you won't 
   // be able to really handle the problem here
}
catch /* ... */ {
}
Michael Burr
la source
2
Bien que vous puissiez enregistrer une erreur de diagnostic ici, vous pouvez peut-être renvoyer l'exception. Parfois, la capture de données de premier échec peut être très utile.
djna
Ou encapsulez l'exception dans une RuntimeException avec des informations de diagnostic dans la chaîne de message. Gardez les informations ensemble.
Thorbjørn Ravn Andersen
Maintenant (en 2018) je ne peux plus être d'accord et dans de tels cas, nous devrions favoriser le retourOptional<>
Piotr Müller
2

Pour certains scénarios, vous souhaitez remarquer un échec dès qu'il se produit.

Vérifier NULL et ne pas affirmer (pour les erreurs du programmeur) ou lancer (pour les erreurs de l'utilisateur ou de l'appelant) dans le cas d'échec peut signifier que les plantages ultérieurs sont plus difficiles à localiser, car le cas étrange d'origine n'a pas été trouvé.

De plus, ignorer les erreurs peut conduire à des failles de sécurité. Peut-être que la nullité est venue du fait qu'un tampon a été écrasé ou similaire. Maintenant, vous ne plantez pas , ce qui signifie que l'exploitant a une chance de s'exécuter dans votre code.

Drew Hoskins
la source
2

Quelles alternatives voyez-vous pour renvoyer null?

Je vois deux cas:

  • findAnItem (id). Que doit-il faire si l'élément n'est pas trouvé

Dans ce cas, nous pourrions: Renvoyer Null ou lancer une exception (cochée) (ou peut-être créer un élément et le renvoyer)

  • listItemsMatching (critères) que doit-il retourner si rien n'est trouvé?

Dans ce cas, nous pourrions retourner Null, renvoyer une liste vide ou lancer une exception.

Je pense que return null peut être moins bon que les alternatives car il oblige le client à se souvenir de vérifier la nullité, les programmeurs oublient et codent

x = find();
x.getField();  // bang null pointer exception

En Java, lever une exception vérifiée, RecordNotFoundException, permet au compilateur de rappeler au client de traiter le cas.

Je trouve que les recherches retournant des listes vides peuvent être très pratiques - il suffit de remplir l'écran avec tout le contenu de la liste, oh c'est vide, le code "fonctionne juste".

djna
la source
3
Lancer des exceptions pour indiquer une condition qui devrait se produire pendant le déroulement normal du programme conduit à un code vraiment laid, du type try {x = find ()} catch (RecordNotFound e) {// faire des choses}.
quant_dev
Le renvoi de listes vides est une bonne solution, mais uniquement lorsque la méthode se trouve dans un contexte pouvant renvoyer des listes. Pour les situations «findById», vous devez renvoyer null. Je n'aime pas les exceptions RecordNotFound.
Thilo
C'est donc le nœud de notre différence d'opinion. À mes yeux, il n'y a pas beaucoup de différence de beauté entre x = find (); if (x = null) {work} else {do ​​stuff} et essayez catch. Et, si nécessaire, je suis prêt à sacrifier la beauté pour l'exactitude du code. Trop souvent dans ma vie, je rencontre du code où les valeurs de retour n'ont pas été vérifiées.
djna
1

Parfois, renvoyer NULL est la bonne chose à faire, mais plus particulièrement lorsque vous avez affaire à des séquences de différentes sortes (tableaux, listes, chaînes, ce que vous avez), il est probablement préférable de renvoyer une séquence de longueur nulle, car elle conduit à un code plus court et, espérons-le, plus compréhensible, sans nécessiter beaucoup plus d'écriture de la part de l'implémenteur d'API.

Vatine
la source
1

Faites-leur appeler une autre méthode après coup pour savoir si l'appel précédent était nul. ;-) Hé, c'était assez bien pour JDBC

David Plumpton
la source
1

L'idée de base derrière ce fil est de programmer de manière défensive. Autrement dit, code contre l'inattendu. Il existe un éventail de réponses différentes:

Adamski suggère de regarder Null Object Pattern, cette réponse étant votée pour cette suggestion.

Michael Valenty suggère également une convention de dénomination pour dire au développeur ce à quoi on peut s'attendre. ZeroConcept suggère une utilisation correcte d'Exception, si c'est la raison de NULL. Et d'autres.

Si nous établissons la «règle» selon laquelle nous voulons toujours faire de la programmation défensive, nous pouvons voir que ces suggestions sont valables.

Mais nous avons 2 scénarios de développement.

Classes "créées" par un développeur: l'auteur

Classes "consommées" par un autre (peut-être) développeur: le développeur

Indépendamment du fait qu'une classe renvoie NULL pour les méthodes avec une valeur de retour ou non, le développeur devra tester si l'objet est valide.

Si le développeur ne peut pas faire cela, alors cette classe / méthode n'est pas déterministe. Autrement dit, si "l'appel de méthode" pour obtenir l'objet ne fait pas ce qu'il "annonce" (par exemple, getEmployee), il a rompu le contrat.

En tant qu'auteur d'une classe, je veux toujours être aussi gentil et défensif (et déterministe) lors de la création d'une méthode.

Donc, étant donné que NULL ou NULL OBJECT (par exemple if (employee as NullEmployee.ISVALID)) doit être vérifié et que cela peut devoir se produire avec une collection d'employés, alors l'approche d'objet nul est la meilleure approche.

Mais j'aime aussi la suggestion de Michael Valenty de nommer la méthode qui DOIT retourner null, par exemple getEmployeeOrNull.

Un auteur qui lève une exception supprime le choix du développeur de tester la validité de l'objet, ce qui est très mauvais sur une collection d'objets, et oblige le développeur à gérer les exceptions lors de la création de branches de son code consommateur.

En tant que développeur consommant la classe, j'espère que l'auteur me donnera la possibilité d'éviter ou de programmer pour la situation nulle à laquelle leur classe / méthodes peuvent être confrontées.

Donc, en tant que développeur, je programmerais de manière défensive contre NULL à partir d'une méthode. Si l'auteur m'a donné un contrat qui renvoie toujours un objet (NULL OBJECT le fait toujours) et que cet objet a une méthode / propriété par laquelle tester la validité de l'objet, alors j'utiliserais cette méthode / propriété pour continuer à utiliser l'objet , sinon l'objet n'est pas valide et je ne peux pas l'utiliser.

L'essentiel est que l'auteur de la classe / des méthodes doit fournir des mécanismes qu'un développeur peut utiliser dans sa programmation défensive. Autrement dit, une intention plus claire de la méthode.

Le développeur doit toujours utiliser une programmation défensive pour tester la validité des objets renvoyés par une autre classe / méthode.

Cordialement

GregJF

GregJF
la source
0

D'autres options à cela, sont: renvoyer une valeur qui indique le succès ou non (ou le type d'une erreur), mais si vous avez juste besoin d'une valeur booléenne qui indiquera le succès / échec, renvoyer null en cas d'échec et un objet pour le succès ne le ferait pas être moins correct, puis renvoyer vrai / faux et obtenir l'objet via le paramètre.
Une autre approche consisterait à utiliser l'exception pour indiquer les échecs, mais ici - il y a en fait beaucoup plus de voix, qui disent que c'est une mauvaise pratique (car l'utilisation d'exceptions peut être pratique mais présente de nombreux inconvénients).
Donc, personnellement, je ne vois rien de mal à renvoyer null pour indiquer que quelque chose s'est mal passé, et à le vérifier plus tard (pour savoir si vous avez réussi ou non). De plus, penser aveuglément que votre méthode ne retournera pas NULL, puis basera votre code dessus, peut entraîner d'autres erreurs, parfois difficiles à trouver (bien que dans la plupart des cas, cela plantera simplement votre système :), comme vous le ferez référence à 0x00000000 tôt ou tard).

Marcin Deptuła
la source
0

Des fonctions nulles involontaires peuvent survenir pendant le développement d'un programme complexe, et comme du code mort, de telles occurrences indiquent de graves défauts dans les structures du programme.

Une fonction ou méthode nulle est souvent utilisée comme comportement par défaut d'une fonction révisable ou d'une méthode remplaçable dans une structure d'objets.

Null_function @wikipedia

Scripter juteux
la source
0

Eh bien, cela dépend bien sûr du but de la méthode ... Parfois, un meilleur choix serait de lever une exception. Tout dépend d'un cas à l'autre.

Denis Biondic
la source
0

Si le code est quelque chose comme:

command = get_something_to_do()

if command:  # if not Null
    command.execute()

Si vous avez un objet factice dont la méthode execute () ne fait rien, et que vous retournez cela au lieu de Null dans les cas appropriés, vous n'avez pas à vérifier le cas Null et pouvez simplement faire:

get_something_to_do().execute()

Donc, ici, le problème n'est pas entre la vérification de NULL et une exception, mais plutôt entre le fait que l'appelant doit gérer différemment les non-cas spéciaux (de quelque manière que ce soit) ou non.

Anon
la source
0

Pour mon cas d'utilisation, j'avais besoin de renvoyer une méthode Map from, puis de rechercher une clé spécifique. Mais si je retourne une carte vide, cela mènera à NullPointerException et alors ce ne sera pas très différent de renvoyer null au lieu d'une carte vide. Mais à partir de Java8, nous pourrions utiliser Optional . Ce qui précède est la raison même pour laquelle le concept facultatif a été introduit.

Aman Gupta
la source
-3

G'day,

Renvoyer NULL lorsque vous ne parvenez pas à créer un nouvel objet est une pratique standard pour de nombreuses API.

Pourquoi diable c'est un mauvais design, je n'en ai aucune idée.

Edit: Ceci est vrai pour les langages où vous n'avez pas d'exceptions comme C où c'est la convention depuis de nombreuses années.

HTH

'Avahappy,

Rob Wells
la source
2
Si vous ne parvenez pas à créer un objet, vous devez vraiment lancer une exception. Si vous ne parvenez pas à trouver un objet qui correspond à une requête, le retour de null est la solution.
Thilo
@Thilo, montre-moi comment faire ça en C et je serai très intéressé.
Rob Wells
@RobWells C n'est pas un langage orienté objet, mais cette question est étiquetée comme "oop"
yegor256
@ yegor256 Vous avez raison. Et j'ai raté la balise OOP originale. Mais, comme BS l'a dit, une classe en C ++ n'est qu'une structure avec quelques fonctions membres supplémentaires ajoutées et une gestion de la mémoire sophistiquée se déroulant en interne. Mais si une API est suuposée pour renvoyer une structure, alors retourner NUL lorsque vous ne pouvez pas créer la structure est souvent la convention.
Rob Wells