Considérez une fonction sans paramètre ( edit: pas nécessairement) qui exécute une seule ligne de code et qui n’est appelée qu’une fois dans le programme (bien qu’il ne soit pas impossible que cela soit nécessaire à nouveau).
Il pourrait effectuer une requête, vérifier certaines valeurs, faire quelque chose impliquant regex ... rien d'obscur ou "hacky".
La raison en serait d'éviter les évaluations difficilement lisibles:
if (getCondition()) {
// do stuff
}
où getCondition()
est la fonction d'une ligne.
Ma question est simplement: est-ce une bonne pratique? Cela me semble bien mais je ne sais pas pour le long terme ...
getCondition
? Si elle est aussi petite et rarement utilisée que vous le dites, lui donner un nom ne sert à rien.Réponses:
Cela dépend de cette ligne. Si la ligne est lisible et concise par elle-même, la fonction peut ne pas être nécessaire. Exemple simpliste:
OTOH, si la fonction donne un bon nom à une ligne de code contenant par exemple une expression complexe et difficile à lire, elle est parfaitement justifiée (pour moi). Exemple élaboré (divisé en plusieurs lignes pour la lisibilité ici):
la source
taxPayer
c'est global dans ce scénario. Peut-être que cette classe estTaxReturn
ettaxPayer
est un attribut.Oui, cela peut être utilisé pour satisfaire les meilleures pratiques. Par exemple, il est préférable de faire travailler une fonction clairement nommée, même si elle ne comporte qu'une ligne, plutôt que d'avoir cette ligne de code dans une fonction plus grande et d'avoir besoin d'un commentaire d'une ligne expliquant ce qu'elle fait. En outre, les lignes de code voisines doivent effectuer des tâches au même niveau d'abstraction. Un contre-exemple serait quelque chose comme
Dans ce cas, il est définitivement préférable de déplacer la ligne médiane dans une fonction nommée de manière sensée.
la source
petrolFlag |= 0x006A;
sans aucune sorte de prise de décision, il serait préférable de simplement direpetrolFlag |= A_B_C;
sans fonction supplémentaire. Vraisemblablement,engageChoke()
ne devrait être appelé que s'ilpetrolFlag
répond à un certain critère et que cela devrait clairement indiquer «J'ai besoin d'une fonction ici». Une réponse mineure, cette réponse est fondamentalementmixLeadedGasoline()
, vous n'auriez pas à le faire!Je pense que dans de nombreux cas, une telle fonction est un bon style, mais vous pouvez envisager une variable booléenne locale comme alternative, dans les cas où vous n'avez pas besoin d'utiliser cette condition ailleurs, par exemple:
Cela donnera un indice au lecteur de code et évitera l’introduction d’une nouvelle fonction.
la source
IsEngineReadyUnlessItIsOffOrBusyOrOutOfService
).En plus de la réponse de Peter , si cette condition doit éventuellement être mise à jour ultérieurement, encapsulez-la de la manière que vous proposez de ne disposer que d'un seul point de montage.
Suivant l'exemple de Peter, si cela
devient ceci
Vous effectuez une édition unique et elle est mise à jour universellement. Maintenabilité sage, c'est un plus.
En ce qui concerne les performances, la plupart des compilateurs optimiseurs suppriment néanmoins l’appel de fonction et insèrent le petit bloc de code en ligne. Optimiser quelque chose comme ceci peut en fait réduire la taille du bloc (en supprimant les instructions nécessaires pour l'appel de fonction, le retour, etc.). Il est donc prudent de le faire même dans des conditions qui pourraient autrement empêcher l'inlining.
la source
seemsGreen
ne soit pas fiable avec des objets légers sera sans importance si le code ne se soucie jamais de savoir si les objets légers sont verts. Cependant, si la définition de "léger" change, de sorte que certains objets non verts qui retournent trueseemsGreen
ne sont pas signalés comme "légers", une telle modification de la définition de "léger" pourrait rompre le code qui teste les objets. être vert". Dans certains cas, les tests de verdissement et de pondération dans le code peuvent rendre la relation entre les tests plus claire que s'il s'agissait de méthodes distinctes.En plus de la lisibilité (ou en complément de celle-ci), cela permet d’écrire des fonctions au niveau d’abstraction approprié.
la source
Ça dépend. Parfois, il est préférable d'encapsuler une expression dans une fonction / méthode, même s'il ne s'agit que d'une ligne. Si c'est compliqué à lire ou si vous en avez besoin à plusieurs endroits, je considère cela comme une bonne pratique. À long terme, il est plus facile à maintenir, car vous avez introduit un point de changement unique et une meilleure lisibilité .
Cependant, parfois, c'est juste quelque chose dont vous n'avez pas besoin. De toute façon, quand l’expression est facile à lire et / ou apparaît juste à la même place, ne l’emballez pas.
la source
Je pense que si vous n'en avez que quelques-uns, c'est correct, mais le problème se pose lorsqu'il y en a beaucoup dans votre code. Et lorsque le compilateur ou l'interpréteur s'exécute (selon la langue utilisée), cette fonction est enregistrée en mémoire. Alors disons que vous en avez 3, je ne pense pas que l'ordinateur le remarquera, mais si vous commencez à avoir une centaine de ces petites choses, le système doit alors enregistrer des fonctions en mémoire qui ne sont appelées qu'une fois et ne sont pas détruites.
la source
J'ai récemment effectué cette opération dans une application que je refacturais, afin d'expliciter le sens réel du code sans commentaires:
la source
if
short? Cette approche locale (lambda) rend laPaymentButton_Click
fonction (dans son ensemble) plus difficile à lire. LelblCreditCardError
dans votre exemple semble être un membre, il enHaveError
est de même un prédicat (privé) valide pour l'objet. J'aurais tendance à faire abstraction de cela, mais je ne suis pas un programmeur C #, alors je résiste.CheckInputs()
???Déplacer cette ligne dans une méthode bien nommée rend votre code plus facile à lire. Beaucoup d'autres ont déjà mentionné cela ("code auto-documenté"). L’autre avantage de l’intégrer dans une méthode est qu’elle facilite le test unitaire. Une fois isolé dans sa propre méthode et testé dans l'unité, vous pouvez être sûr que si / quand un bogue est trouvé, il ne le sera pas dans cette méthode.
la source
Il y a déjà beaucoup de bonnes réponses, mais il y a un cas particulier qui mérite d'être mentionné .
Si votre déclaration d' une ligne nécessite un commentaire et que vous êtes en mesure d'identifier clairement (ce qui signifie: nommez) son objectif, envisagez d'extraire une fonction tout en améliorant le commentaire dans la documentation de l'API. De cette façon, l'appel de fonction est plus facile à comprendre et à comprendre.
Il est intéressant de noter que la même chose peut être faite s’il n’ya actuellement rien à faire, mais un commentaire rappelant les extensions nécessaires (dans un avenir très proche 1) ), alors ceci:
pourrait aussi bien changé en cette
1) vous devriez être vraiment sûr de cela (voir principe de YAGNI )
la source
Si le langage le prend en charge, j'utilise généralement des fonctions anonymes étiquetées pour accomplir cela.
IMHO c'est un bon compromis car il vous donne l'avantage de la lisibilité de ne pas avoir l'expression compliquée encombrant la
if
condition tout en évitant d'encombrer l'espace de noms global / package avec de petites étiquettes à jeter. Cela a l'avantage supplémentaire que la fonction "définition" est exacte là où elle est utilisée, ce qui facilite la modification et la lecture de la définition.Il ne doit pas s'agir uniquement de fonctions de prédicats. J'aime aussi insérer de petites fonctions comme celle-ci dans la chaudière (cela fonctionne particulièrement bien pour la génération de listes pythoniques sans encombrer la syntaxe des crochets). Par exemple, l’exemple suivant trop simplifié lorsqu’on travaille avec PIL en python
la source
[] == False
ou d' une autre équivalence pythonique similaire qui n’est pas «toujours» intuitive. C'est essentiellement une façon de signaler que certaines conditions sont, en fait, un prédicat.[] != False
mais elle[]
est fausse en tant que lorsque jeté sur unlen([complicated expression producing a list]) == 0
, plutôt que d'utiliserTrue if [blah] else False
ce qui oblige encore le lecteur à savoir que [] évalue à Faux.