2008-10-01 7 views
2

Disons que vous avez une fonction qui retourne une date:Est-ce que je devrais retourner null ou appliquer le modèle "objet nul" à une fonction retournant une date?

Date myFunc(paramA, paramB){ 
    //conditionally return a date? 
} 

Est-il approprié de revenir null de cette fonction? Cela semble moche, car il oblige les clients à vérifier null.

Le modèle "objet nul" est un modèle d'implémentation qui répond à cette préoccupation.
Je ne suis pas un grand fan du modèle d'objet nul, mais oui, il est logique de toujours retourner une liste, même si elle est vide, plutôt que de retourner null.
Cependant, disons en Java, une date nulle serait celle qui est effacée et a l'année 1970.

Quel est le meilleur modèle d'implémentation ici?

+0

Qu'entendez-vous par «un qui est effacé»? –

+0

Calendrier c = Calendar.getInstance(); c.clear(); Date myDate = new Date (c.getTime()) entraînera la mise à jour de la date, 1970, etc ... return c.getTime(); –

+0

Cela ne date pas du 1er janvier 1970? Je pourrais me tromper. Trop longtemps depuis que j'ai touché Java. –

Répondre

7

Le modèle d'objet nul n'est pas pour ce que vous essayez de faire. Ce modèle consiste à créer un objet sans fonctionnalité dans son implémentation que vous pouvez passer à une fonction donnée qui nécessite qu'un objet ne soit pas nul. Un exemple est NullProgressMonitor dans Eclipse, qui est une implémentation vide de IProgressMonitor. Si vous renvoyez une date "nulle", comme 1970, vos clients devront toujours vérifier si c'est "null" en voyant si c'est 1970. Et s'ils ne le font pas, un mauvais comportement se produira. Cependant, si vous renvoyez null, leur code échouera rapidement, et ils sauront qu'ils doivent vérifier null. En outre, 1970 pourrait être une date valide.

Vous devez documenter que votre méthode peut retourner null, et c'est tout.

+0

Réponse très intéressante et donc partie de pourquoi j'ai posé la question. Mais beaucoup de gens semblent interpliquer le modèle d'objet nul comme cela a été demandé dans ma question. Par conséquent pourquoi je l'ai posté ... Renvoyer conditionnellement sent malodorant, en ce que c'est comme l'introduction d'un effet secondaire ... –

+0

Tant que vous documentez ce que votre méthode renvoie, votre code sera correct si vous documentez qu'il pourrait retourner null. Les appelants qui rencontrent un NPE sans vérifier la date renvoyée sont alors incorrects car vous avez explicitement documenté le comportement de votre méthode. – MetroidFan2002

5

null est tout à fait acceptable. Cependant, si vous voulez renvoyer null sur une erreur, envisagez de lancer une exception à la place.

+0

Si aucune date n'est une condition valide, je ne l'aurais pas jeté une exception. – 18Rabbit

2

Si c'est possible, une date ne sera pas trouvée alors le zéro a du sens. Sinon, vous finissez par retourner une date magique (comme l'époque de 1970) qui va frustrer les gens qui accèdent à la fonction bien au-delà du simple retour d'un zéro.

document qu'il pourrait retourner null, mais ...

0

Si ce ne est pas un coup de performance j'aime avoir une méthode de requête explicite et utiliser des exceptions:

if(employee.hasCustomPayday()) { 
    //throws a runtime exception if no payday 
    Date d = emp.customPayday(); 
} 
+0

Voulez-vous vraiment utiliser RuntimeException ici? Je sais que c'est la norme en C#, alors peut-être que c'est le genre d'exemple que vous présentez. Cependant, RuntimeExceptions doit être réservé aux cas où vous ne pouvez pas faire grand chose avec la cause, comme une base de données qui disparaît, par exemple. –

+0

Si le développeur a déjà fait la requête alors ils ne devraient pas être obligés de mettre en essai ... attraper. Il détruit un peu l'idiome. Si une exception est renvoyée même si la requête a renvoyé la valeur true, elle mérite probablement une exception d'exécution. –

1

Je ne suis pas fan de le modèle d'objet nul.

Si null est une valeur de retour valide et prévue, retournez-la. Si cela est dû à une condition d'erreur, une exception aurait plus de sens.

Parfois, le vrai problème est que la méthode devrait renvoyer un type plus complexe qui représente plus d'informations. Dans ces cas, il est facile de tomber dans un piège et de retourner un type de base, plus quelques valeurs magiques spéciales pour représenter d'autres états.

+0

Je suis généralement d'accord, mais il peut être logique de renvoyer un objet s'il existe, sinon retourner la valeur null. Tant que ce sont les seules options qui sont une pratique généralement acceptée. – tloach

0

Utilisez des exceptions si ce n'est pas un scénario qui devrait normalement se produire.

Sinon, (s'il s'agit par exemple d'une date de fin pour un événement), renvoyez simplement null.

S'il vous plaît éviter les valeurs magiques en tout cas;)

-1

Vous pouvez essayer d'utiliser un paramètre de sortie

boolean MyFunction(a,b,Date c) 
{ 
    if (good) 
    c.SetDate(....); 
    return good; 

} 

Ensuite, vous pouvez l'appeler

Date theDate = new Date(); 
if(MyFunction(a, b ,theDate) 
{ 
    do stuff with C 
} 

Il vous faut toujours vérifier quelque chose , mais il n'y a pas moyen d'éviter certaines vérifications dans ce scénario.

Bien que SetDate soit obsolète et que l'implémentation du calendrier soit juste moche.

Stupidest modification de l'API Sun jamais fait.

+0

Oui, j'ai entendu une rumeur sur le passage à une conception basée sur JODA en Java 7? –

+0

Ce serait mignon. La mise en œuvre actuelle viole la première règle de la conception du cadre: «Rendre le commun facile, et le plus rare possible». –

+0

Vous devez également vous assurer que le paramètre Date lui-même n'est pas nul, puis lancer un NPE si c'est le cas, ce qui est juste plus de code sur tout cela. –

1

Il semble que les résultats attendus de cette méthode soient une date, ou aucun résultat trouvé. Le cas none found est généralement représenté en retournant null. Bien que certains utiliseraient une exception pour représenter ce cas, je ne le ferais pas (car c'est un résultat attendu et je n'ai jamais été un fan de traitement par exception).

Le motif d'objet nul n'est pas approprié pour ce cas, comme cela a été indiqué. En fait, d'après ma propre expérience, ce n'est pas approprié dans de nombreux cas. Bien sûr, j'ai un certain biais dû à une certaine expérience avec ce qui est mal utilisé ;-)

Questions connexes