Est-ce correct pour une méthode factory de renvoyer null?

Je me demande quelle est la meilleure pratique ici. Est-ce une bonne pratique pour une méthode factory de renvoyer null si elle ne peut rien créer? Voici un exemple:

ICommand command = CommandFactory.CreateCommand(args); if (command != null) command.Execute(); else // do something else if there is no command 

Une alternative serait de renvoyer une NullCommand ou quelque chose, je suppose, mais quelle est la meilleure pratique?

Je pense qu’il est potentiellement raisonnable pour une méthode factory de renvoyer null dans certaines situations, mais pas si c’est une méthode appelée CreateCommand . Si c’était GetCommand ou FetchCommand , ça pourrait aller … mais une méthode Create devrait renvoyer une exception en cas d’échec, je suggérerais.

Bien entendu, le choix de renvoyer null dans cette situation dépend de la situation dans son ensemble. (Existe-t-il par exemple une implémentation d’object null raisonnable que vous pourriez renvoyer?)

Retourner null dans ce cas rendra votre méthode plus difficile à utiliser; les clients doivent être conscients d’une condition d’échec implicite. Au lieu de cela, émettez une exception et vous pouvez également fournir une méthode distincte pour que les clients testent cette condition:

 if (CommandFactory.CanCreate(args)) { ICommand command = CommandFactory.Create(args); command.Execute(); } 

Ou rendre l’usine instanciable; ce qui serait mieux si vous avez besoin de prétraiter les args :

 CommandFactory factory = new CommandFactory(args); if (factory.IsValid()) { ICommand command = factory.Create(); command.Execute(); } 

L’interface de la fabrique indique maintenant clairement et explicitement que la création peut échouer, mais le client doit néanmoins utiliser la méthode de vérification. Une autre option est la suivante:

 ICommand command; if (CommandFactory.TryCreate(args, out command)) { // creation succeeded ... } 

Je suis d’accord avec Jon Skeet. CreateCommand implique clairement la construction.

Si vous ne lancez pas d’ Exception , dans ce scénario, je choisirais personnellement l’implémentation de NullCommand , afin d’éviter les instructions conditionnelles dans tous les consommateurs et les erreurs possibles de NullReferenceException .

Renvoyer Null n’a de sens que s’il existe une raison pour laquelle vous voudriez que l’utilisateur doive vérifier la valeur null à chaque fois qu’il appelle Create. Normalement, vous considéreriez ce qui suit comme un modèle d’utilisation parfaitement valide:

 var obj = MyFactory.CreateThing(); obj.DoSomething(); 

Mais ce que vous proposez, c’est de forcer le modèle d’utilisation suivant:

 var obj = MyFactory.CreateThing(); if (obj == Null) { // Handle null condition } else { obj.DoSomething(); } 

Normalement, le scénario Null signifierait une sorte d’échec, auquel cas une exception aurait probablement le plus de sens. Mais finalement, vous êtes le créateur de musique ici et devez décider de ce qui est sensé dans le monde que vous construisez.