S'il existe une méthode
bool DoStuff() {
try {
// doing stuff...
return true;
}
catch (SomeSpecificException ex) {
return false;
}
}
faut-il plutôt l'appeler IsStuffDone()
?
Les deux noms peuvent être mal interprétés par l'utilisateur: si le nom est DoStuff()
pourquoi renvoie-t-il un booléen? Si le nom est IsStuffDone()
, il n'est pas clair si la méthode effectue une tâche ou vérifie uniquement son résultat.
Existe-t-il une convention pour ce cas? Ou une approche alternative, car celle-ci est considérée comme défectueuse? Par exemple, dans les langages qui ont des paramètres de sortie, comme C #, une variable d'état booléenne pourrait être transmise à la méthode comme une et le type de retour de la méthode serait void
.
EDIT: Dans mon problème particulier, la gestion des exceptions ne peut pas être directement déléguée à l'appelant, car la méthode fait partie d'une implémentation d'interface. Par conséquent, l'appelant ne peut pas être chargé de traiter toutes les exceptions de différentes implémentations. Il ne connaît pas ces exceptions. Cependant, l'appelant peut gérer une exception personnalisée comme StuffHasNotBeenDoneForSomeReasonException
comme cela a été suggéré dans réponse et commentaire de npinti .
Dans .NET, vous avez souvent des paires de méthodes où l'une d'entre elles peut lever une exception (DoStuff
), et l'autre retourne un état booléen et, en cas d'exécution réussie, le résultat réel via un paramètre out (TryDoStuff
).
(Microsoft appelle cela "Try-Parse Pattern" , car l'exemple le plus important est peut-être les méthodes TryParse
de divers types primitifs.)
Si le préfixe Try
n'est pas courant dans votre langue, vous ne devriez probablement pas l'utiliser.
Et si vous jetiez simplement l'exception au code d'appel?
De cette façon, vous déléguez la gestion des exceptions à quiconque utilise votre code. Et si, à l’avenir, vous souhaitiez procéder comme suit:
FileNotFoundException
est lancé, effectuez l'action BSi vous rejetez votre exception, la modification ci-dessus impliquerait simplement l'ajout d'un bloc supplémentaire catch
. Si vous la laissez telle quelle, vous devrez changer la méthode et l'endroit d'où la méthode est appelée, qui, selon la complexité du projet, peuvent se trouver à plusieurs endroits.
DoStuff()
suffit, et la valeur de retour de la fonction doit être documentée, et vous n'avez pas besoin de le mentionner dans le nom de la fonction, à la recherche de nombreuses API disponibles:
// this method update and return the number affected rows
// called update instead of updateAndGetAffectedCount
$affected = $query->update(/* values */);
// Remove item from the List
// returns true if item is successfully removed; otherwise, false.
public bool Remove( T item )
En Java, la collection API définit ne méthode add qui renvoie un booléen. Il retourne essentiellement si l'ajout a changé la collection. Ainsi, pour un List
, il retournera généralement vrai, puisque l'élément a été ajouté, tandis que pour un Set
, il pourrait retourner faux, si l'élément était déjà là, puisque Set
s permet chaque article unique au plus une fois.
Cela dit, si vous ajoutez un élément qui n'est pas autorisé par la collection, par exemple, une valeur nulle, l'ajout lancera un NullPointerException
plutôt que de retourner false.
Lorsque vous appliquez la même logique à votre cas, pourquoi devez-vous renvoyer un booléen? Si c'est pour cacher une exception, ne le faites pas. Jetez simplement l'exception. De cette façon, vous pouvez voir ce qui a mal tourné. Si vous avez besoin d'un booléen, car cela n'a peut-être pas été fait, pour une autre raison qu'une exception, nommez la méthode DoStuff()
, car cela représente le comportement. Ça fait des trucs.
J'ai généralement des méthodes qui retournent un OperationResult
(ou OperationResult<T>
) Et définissent la propriété IsSuccess
sur OperationResult
de manière appropriée. Si la méthode "habituelle" est vide, retournez OperationResult
, si la méthode "habituelle" renvoie un objet, retournez OperationResult<T>
Et définissez la propriété Item
sur la OperationResult
convenablement. Je suggère également d'avoir des méthodes sur OperationResult
telles que .Failed(string reason)
et .Succeeded(T item)
. OperationResult
devient rapidement un type familier dans vos systèmes et les développeurs apprennent à le gérer.
Peut échouer pour différentes raisons, exception, conditions normales, donc utiliserait ceci:
boolean doStuff() - returns true when successful
Il est important de documenter ce que signifie le booléen.
Je choisirais un nom basé sur le rôle principal de la méthode. Le fait que cette méthode renvoie une valeur booléenne ne requiert pas le préfixe "Is". Ayons un peu de code Java, qui utilise le préfixe 'Is' assez largement. Regardez Java.io.File.delete()
. Il retourne boolean
, mais il n'est pas appelé isFileDeleted()
. La raison en est que le rôle principal du métod est de supprimer un fichier. Quelqu'un appelle cette méthode avec l'intention de supprimer un fichier.
Le booléen est là juste pour communiquer le résultat du travail. D'un autre côté, voyons Java.util.Map.isEmpty()
. Évidemment, vous appelez une telle méthode pour savoir si la collection est vide. Vous ne voulez rien faire. Vous voulez juste savoir quel est l'état actuel.
Donc, personnellement, je resterais définitivement avec DoStuff()
.
C'est quelque chose de très important pour moi. Souvent, lorsque je maintiens un code hérité, je tombe sur quelque chose que j'appelle personnellement la "méthode du mensonge". Le nom suggère l'action A, mais le corps fait l'action B. L'exemple le plus bizzare étant une méthode getter changeant les données dans la base de données.
Cela dépend vraiment de la langue que vous utilisez. Comme pour certaines langues, il existe des conventions et des protocoles qui n'existent vraiment pas dans de nombreuses langues ou pas du tout.
Par exemple, dans le langage Objective-C et les noms de méthode SDK iOS/Mac OS X vont généralement dans le sens de:
- (returndatatype) viewDidLoad {
- (returndatatype) isVisible {
- (returndatatype) appendMessage:datatype variablename with:datatype variablename {
Comme vous pouvez le voir, il existe une méthode appelée viewDidLoad. Je préfère utiliser ce type de dénomination chaque fois que je crée mes propres applications. Cela pourrait être utilisé pour vérifier si quelque chose devait se produire comme vous l'avez dit. Je crois que vous pensez trop profondément à ce que vous nommez vos méthodes. La plupart des méthodes renvoient le statut de ce qu'elles font indépendamment, par exemple:
En PHP, mysql_connect () retournera false si la connexion échoue. Il ne le dit pas, mais il le fait et la documentation le dit, il ne peut donc pas être mal interprété par le programmeur.
Je voudrais suggérer d'utiliser le préfixe "Try". Il s'agit d'un modèle bien connu pour les situations où la méthode peut réussir ou non. Ce modèle de dénomination a été utilisé par Microsoft dans . NET Framework (par exemple, TryParseInt).
Mais, peut-être qu'il ne s'agit pas de nommer. Il s'agit de la façon dont vous concevez les paramètres d'entrée/sortie de votre méthode.
Mon idée est que si une méthode a une valeur de retour, le but de l'appel de cette méthode devrait être d'obtenir cette valeur de retour. Par conséquent, vous devez éviter d'utiliser le type de retour pour indiquer l'état d'une opération.
En C #, je préfère utiliser un paramètre out. En utilisant une sortie, je marque le paramètre comme paramètre secondaire. Surtout que C # 6 supportera la déclaration de variable en ligne.
DoStuff(out var isStuffDone); // The out parameter name clearly states its purpose.
DoStuff(out var _); // I use _ for naming parameters that I am ignoring.