Chaque fois que je me retrouve à écrire la même logique plusieurs fois, je la colle habituellement dans une fonction, de sorte qu'il n'y a qu'un seul endroit dans mon application où je dois conserver cette logique. Un effet secondaire est que je finis parfois avec une ou deux fonctions de ligne telles que:
function conditionMet(){
return x == condition;
}
OU
function runCallback(callback){
if($.isFunction(callback))
callback();
}
Est-ce paresseux ou une mauvaise pratique? Je demande seulement parce que cela entraîne un plus grand nombre d'appels de fonction pour de tout petits morceaux de logique.
programming-practices
coding-standards
Mark Brown
la source
la source
Assert.AreEqual<int>(expected, actual, message, arg1, arg2, arg3, ...);
. Le second est bien tel quel. Je pourrais éventuellement inclure un drapeau bool optionnel qui dicterait s'il fallait lever une exception / etc. dans le cas où le rappel n'est pas une fonction.def yes(): return 'yes'
Réponses:
Hé hé, oh M. Brown, si seulement je pouvais persuader tous les développeurs que je rencontre de garder leurs fonctions aussi petites que cela, croyez-moi, le monde du logiciel serait un meilleur endroit!
1) La lisibilité de votre code augmente de dix fois.
2) Si facile à comprendre le processus de votre code en raison de la lisibilité.
3) SEC - Ne te répète pas - Tu t'y conforme très bien!
4) testable. Les fonctions minuscules sont un million de fois plus faciles à tester que les méthodes à 200 lignes que nous voyons trop souvent.
Oh, et ne vous inquiétez pas du "saut de fonction" en termes de performances. Les versions "Release" et les optimisations du compilateur s'en occupent très bien, et les performances représentent 99% du temps ailleurs dans la conception des systèmes.
Est-ce paresseux? - Bien au contraire!
Est-ce une mauvaise pratique? - Absolument pas. Mieux vaut utiliser cette méthode de fabrication que les boules de goudron ou les "Objets divins" qui sont trop communs.
Continuez le bon travail mon collègue artisan;)
la source
Je dirais qu'une méthode refactorisée est trop courte si:
Ex:
ou...
Ex:
Cela pourrait être un modèle valide, mais je voudrais simplement intégrer la méthode configureDialog (), dans cet exemple, à moins que je ne souhaite le remplacer ou réutiliser ce code ailleurs.
la source
Une fonction peut-elle être trop courte? En général non.
En fait, le seul moyen de s'assurer que:
Est de garder vos fonctions aussi petites que possible. Ou, en d'autres termes, extrayez des fonctions de vos fonctions jusqu'à ce que vous ne puissiez plus en extraire. J'appelle ça "Extrait jusqu'à ce que tu tombes".
Pour expliquer cela: une fonction est une étendue avec des blocs de fonctionnalités qui communiquent par des variables. Une classe est également une étendue avec des morceaux de fonctionnalités qui communiquent par des variables. Ainsi, une fonction longue peut toujours être remplacée par une ou plusieurs classes avec une petite méthode.
En outre, une fonction suffisamment grande pour vous permettre d’en extraire une autre, fait plus d’une chose par définition . Donc , si vous pouvez extraire une fonction d' une autre, vous devez extraire cette fonction.
Certains craignent que cela ne mène à une prolifération de fonctions. Ils ont raison. Ce sera. C'est en fait une bonne chose. C'est bien parce que les fonctions ont des noms. Si vous faites attention à choisir de bons noms, ces fonctions agissent comme des panneaux de signalisation qui guident les autres personnes dans votre code. En effet, des fonctions bien nommées au sein de classes bien nommées au sein d'espaces de noms bien nommés constituent l'un des meilleurs moyens de s'assurer que vos lecteurs NE se perdent PAS.
Il y a beaucoup plus à ce sujet dans l'épisode III de Clean Code sur cleancoders.com
la source
Wow, la plupart de ces réponses ne sont pas très utiles du tout.
Aucune fonction dont l'identité est sa définition ne devrait être écrite . Autrement dit, si le nom de la fonction est simplement le bloc de code de la fonction écrit en anglais, ne l'écrivez pas en tant que fonction.
Considérez votre fonction
conditionMet
et cette autre fonction,addOne
(pardonnez-moi pour mon JavaScript rouillé):conditionMet
est une définition conceptuelle appropriée;addOne
est une tautologie .conditionMet
est bon parce que vous ne savez pas ce que celaconditionMet
implique simplement en disant "condition satisfaite", mais vous pouvez voir pourquoiaddOne
est idiot si vous le lisez en anglais:Pour l'amour de tout ce qui pourrait encore être sacré, n'écrivez pas de fonctions tautologiques!
(Et pour la même raison, n'écrivez pas de commentaires pour chaque ligne de code !)
la source
function nametoolong() { return name.size > 15; }
oufunction successorIndex(x) { return x + 1; }
Alors le problème avec vos fonctions est en réalité juste qu'elles s'appellent mal.Je dirais que si vous pensez que l'intention d'un code peut être améliorée en ajoutant un commentaire, alors plutôt que d'ajouter ce commentaire, extrayez le code dans sa propre méthode. Peu importe la taille du code.
Ainsi, par exemple, si votre code devait ressembler à ceci:
faites le ressembler à ceci à la place:
avec
Ou en d'autres termes, il ne s'agit pas de la longueur de la méthode, mais du code auto-documenté.
la source
if x == PIXEL_ON
. L'utilisation d'une constante peut être aussi descriptive que l'utilisation d'une méthode et est un peu plus brève.Je pense que c'est exactement ce que vous voulez faire. À l'heure actuelle, cette fonction peut ne comporter qu'une ou deux lignes, mais avec le temps, elle pourrait se développer. De plus, avoir plus d'appels de fonction vous permet de lire les appels de fonction et de comprendre ce qui se passe à l'intérieur. Cela rend votre code très sec (ne vous répétez pas) ce qui est beaucoup plus facile à gérer.
la source
conditionMet
est un nom trop générique, et ne prend aucun argument, il teste donc un état? (x == xCondition) est dans la plupart des langues et situations aussi expressive que 'xConditition'.Je suis d'accord avec tous les autres messages que j'ai vus. C'est bon style.
La surcharge d'une méthode aussi petite peut être nulle, car l'optimiseur peut optimiser l'appel à distance et le code en ligne. Un code simple comme celui-ci permet à l'optimiseur de faire de son mieux.
Le code doit être écrit pour plus de clarté et de simplicité. J'essaie de limiter une méthode à l'un des deux rôles suivants: prendre des décisions; ou effectuer un travail. Cela peut générer des méthodes à une ligne. Plus je réussis à le faire, meilleur je trouve mon code.
Un tel code a tendance à avoir une cohésion élevée et un couplage faible, ce qui est une bonne pratique de codage.
EDIT: Une note sur les noms de méthodes. Utilisez un nom de méthode qui indique ce que la méthode ne fait pas. Je trouve que verb_noun (_modifier) est un bon schéma de nommage. Cela donne des noms comme Find_Customer_ByName plutôt que Select_Customer_Using_NameIdx. Le second cas est susceptible de devenir incorrect lorsque la méthode est modifiée. Dans le premier cas, vous pouvez échanger la mise en œuvre complète de la base de données client.
la source
Refactoriser une ligne de code dans une fonction semble excessif. Il peut y avoir des cas exceptionnels, tels que des lignes ou des expansions très compliquées, mais je ne le ferais pas à moins de savoir que la fonction se développera dans le futur.
et votre premier exemple suggère l'utilisation de globals (qui peuvent ou ne peuvent pas parler d'autres problèmes dans le code), je le reformulerais plus avant et ferais ces deux variables comme paramètres:
L'
conditionMet
exemple peut être utile si la condition est longue et répétitive, telle que:la source
conditionMet
fonction est juste un==
opérateur prolixe . Ce n'est probablement pas utile.conditionMet (x, relation condition) {
ici, où vous passez x, '==' et relation. Ensuite, vous n'avez pas besoin de répéter le code pour '<', '>', '<=', '! =' Et ainsi de suite. De l'autre côté - la plupart des langages ont ces constructions intégrées comme des opérateurs (x == condition) le font exactement. Fonctions pour les déclarations atomiques est un pas de trop.Considère ceci:
Une simple fonction de détection de collision:
Si vous écriviez cette "simple" ligne dans votre code tout le temps, vous pourriez éventuellement faire une erreur. De plus, il serait très pénible d’écrire cela encore et encore.
la source
#define
;)Non, et c'est rarement un problème. Maintenant, si quelqu'un estime qu'aucune fonction ne devrait être plus longue qu'une ligne de code (si seulement cela pouvait être aussi simple), ce serait un problème et, à certains égards, paresseux, car ils ne pensent pas à ce qui est approprié.
la source
function isAdult () = { age >= 18; }
mais sûrement pasisAtLeast18
.Je dirais qu'ils sont trop courts, mais c'est mon opinion subjective.
Parce que:
Les fonctions qui sont longues sont mauvaises, mais les fonctions qui sont plus courtes que 3 lignes et qui exécutent seulement 1 chose sont également mauvaises.
Donc, je dirais seulement écrire petite fonction si c'est:
Je parie que le prochain développeur (senior) aura mieux à faire que de se souvenir de toutes vos fonctions SetXToOne. Ainsi, ils se transformeront bientôt en poids mort.
la source
Je n'aime pas l'exemple non. 1, à cause du nom générique.
conditionMet
ne semble pas être générique, donc il représente une condition spécifique? CommeCe serait bien. C'est une différence sémantique, alors que
ne serait pas bien pour moi.
Peut-être qu'il est souvent utilisé et peut faire l'objet de modifications ultérieures:
est bien aussi. En l'utilisant plusieurs fois, il vous suffit de changer d'un seul lieu, le cas échéant. Peut-être que la crème fouettée sera possible demain.
n'est pas atomique, et devrait vous donner une belle occasion de test.
Bien sûr, si vous avez besoin de passer une fonction, transmettez ce que vous voulez et écrivez des fonctions qui paraissent ridicules.
Mais en général, je vois beaucoup plus de fonctions, qui sont trop longues, que de fonctions qui sont trop courtes.
Un dernier mot: Certaines fonctions semblent seulement appropriées, car elles sont écrites trop verbeuses:
Si vous voyez que c'est la même chose que
vous n'aurez pas de problème avec
au lieu de
la source
Il n'y a pas de code comme pas de code!
Restez simple et ne compliquez pas trop les choses.
Ce n'est pas être paresseux, c'est faire votre travail!
la source
Oui, son ok pour avoir une fonction de code court. Dans le cas de méthodes telles que "getters", "setters", "accessors" est très courant, comme indiqué dans les réponses précédentes.
Parfois, ces fonctions "accesors" courtes sont virtuelles, car lorsqu'elles sont remplacées dans des sous-classes, les fonctions auront plus de code.
Si vous voulez que votre fonction ne soit pas si courte, eh bien, dans de nombreuses fonctions, que ce soit globales ou méthodes, j'utilise généralement une variable "result" (style pascal) au lieu d'un retour direct, c'est très utile lorsque vous utilisez un débogueur.
la source
Trop court n'est jamais un problème. Quelques raisons pour les fonctions courtes sont:
Réutilisabilité
Par exemple, si vous avez une fonction, comme une méthode set, vous pouvez l'affirmer pour vous assurer que les paramètres sont valides. Cette vérification doit être effectuée partout où la variable est définie.
Maintenabilité
Vous pouvez utiliser une déclaration qui, à votre avis, pourrait changer. Par exemple, vous affichez maintenant un symbole dans une colonne, mais cela pourrait changer ultérieurement (ou même un bip).
Uniformité
Vous utilisez, par exemple, le motif de façade et la seule chose que fait une fonction est de la transmettre à une autre sans changer d'argument.
la source
Lorsque vous nommez une section de code, c'est essentiellement pour lui donner un nom . Cela peut être dû à plusieurs raisons, mais le point crucial est que vous puissiez lui donner un nom explicite qui ajoute à votre programme. Des noms comme "addOneToCounter" n’ajouteraient rien, mais le
conditionMet()
feraient.Si vous avez besoin d'une règle pour déterminer si l'extrait est trop court ou trop long, déterminez le temps qu'il vous faut pour trouver un nom significatif à l'extrait. Si vous ne pouvez pas le faire dans un délai raisonnable, la taille de l'extrait de code ne convient pas.
la source
Non, mais ça peut être trop concis.
Rappelez-vous: le code est écrit une fois, mais lu plusieurs fois.
N'écrivez pas de code pour le compilateur. Ecrivez-le pour les futurs développeurs qui devront maintenir votre code.
la source
Oui, ma fonction peut être de plus en plus petite et, qu’elle soit bonne ou mauvaise, cela dépend de la langue / du framework que vous utilisez.
À mon avis, je travaille principalement sur les technologies frontales. Les petites fonctions sont principalement utilisées en tant que fonctions d'assistance que vous serez obligé de les utiliser comme beaucoup lorsque vous travaillez avec de petits filtres et en utilisant la même logique dans votre application. Si votre application a trop de logique commune, il y aura alors une tonne de petites fonctions.
Mais dans une application où vous n'avez pas de logique commune, vous ne serez pas obligé de créer de petites fonctions, mais vous pouvez diviser votre code en segments où il devient facile pour vous de gérer et de comprendre.
En général, casser votre gros code en petite fonction est une très bonne approche. Dans les cadres et les langages modernes, vous serez obligé de le faire, par exemple
est une fonction anonyme dans ES 2017 JavaScript et Typescript
Dans le code ci-dessus, vous pouvez voir 3 déclarations de fonction et 2 appels de fonction. Il s'agit d'un simple appel de service dans Angular 4 avec Typescript. Vous pouvez le considérer comme vos exigences
Les fonctions ci-dessus sont 3 fonctions anonymes en langage clojure
Le précédent est une déclaration fonctionnelle en clojure
Donc oui, FUNCTIONS peut être aussi petit, mais que ce soit bon ou mauvais si vous avez des fonctions comme:
Bien que ce ne soit pas une bonne pratique, mais si vous utilisiez cette fonction dans une balise HTML comme nous le faisons dans Angular Framework, si Incrément ou Décrément ne sont pas pris en charge dans les modèles HTML angulaires, alors cela aurait été la solution moi.
Prenons un autre exemple
L'exemple ci-dessus est un must lors de la lecture de tableaux dans des modèles angulaires HTML. Donc, parfois, vous devrez créer de petites fonctions
la source
Je suis en désaccord avec presque réponse donnée à ce moment.
Récemment, j'ai trouvé un collègue qui écrit tous les membres de la classe comme suit:
Cela pourrait être un bon code dans des cas sporadiques, mais sûrement pas si vous définissez de nombreuses classes ayant de très nombreuses propriétés. Je ne veux pas dire, avec ceci, que des méthodes comme celles ci-dessus ne seront pas écrites. Mais si vous finissez par écrire la plus grande partie du code en tant que "wrapper" de la logique réelle, il y a quelque chose qui ne va pas.
Le programmeur manque probablement de logique générale, de peur des changements futurs et de refactoriser le code.
La définition de l'interface est un besoin réel; En effet, si vous devez définir et obtenir une propriété simple (sans beaucoup de logique, ce qui raccourcit le membre), cela sera possible. Mais si le besoin réel pouvait être analysé différemment, pourquoi ne pas définir une interface plus intuitive?
Pour vraiment répondre à la question, bien sûr que non, et la raison en est très évidente: la méthode / propriété / quoi que ce soit doit être défini pour ce dont il a besoin. Même une fonction virtuelle vide a sa raison d'être.
la source