Partage

Fonctions sur 50 lignes max ?

oragnisation de code

Sujet résolu
3 septembre 2011 à 22:13:16

bonjour,
Suite à la remontée d'un post concernant l'optimisation du code, et étant dans une phase où j'arrive à atteindre mes objectifs (raisonnables quand-même ;) ) je me retrouve à essayer de réviser mes précédents programmes pour qu'ils soient au maximum ecrits dans les règles de l'art.

J'arrive sans (trop) de problème à faire en sorte que mes fonctions de base soient suffisament courtes pour qu'elle tiennent à l'écran mais par contre, la fonction qui, elle, gère les appels de ces fonctions est toujours assez imposante.

Dans le post cité plus haut, on m'a gentilment proposé le bûcher (je veux des cendres) lorsque j'ai écrit qu'il était assez difficile de respecter la règle des 50 lignes (ou 40 ou 80 selon...mais on s'est bien compris) lorsque l'on avait ce genre de code :

switch (lettre)
{
   case 'a':
      faire ceci;
   break;

  case 'b':
      faire cela;
  break;

  etc...;
}


"surtout si tu vas jusqu'à z".

Du coup je me suis posé la question de comment éviter ce genre de truc si par exemple j'attribue une fonction différente à chaque touche du clavier.

Une astuce à proposer ?

Merci d'avance pour les infos...
Nouveaux Modules pour la CEV_lib : éditeur de map (tiles) + météo. Testez le rendu ici. w pour alterner météo.
3 septembre 2011 à 22:56:27

Ca dépend, qu'est-ce que tu comptes mettre dans tes cases ?
Si c'est juste un appel de fonction, essaye d'avoir toujours le même prototype et crée une table de correspondance entre lettre<->fonction. Ca donnerai genre un truc :

struct {
  char c;
  int (*f)(int, int); /* Tu mets ce que tu veux, j'ai mis ça au pif)
} tab = {
  { 'a', fonctionA },
  { 'b', fonctionB },
  ...
};
3 septembre 2011 à 23:11:13

Dans ce cas là autant utilisé un tableau de pointeurs sur fonction, et on appelle la fonction comme ça non: tab[lettre-'a']()?
Mais bon c'est vachement contraignant d'avoir le même prototype pour chaque fonction.

Citation

Dans le post cité plus haut, on m'a gentilment proposé le bûcher (je veux des cendres) lorsque j'ai écrit qu'il était assez difficile de respecter la règle des 50 lignes (ou 40 ou 80 selon...mais on s'est bien compris) lorsque l'on avait ce genre de code :

Si pour chaque cas tu appelles une fonction différente, je vois pas ce qu'on pourrait faire de mieux qu'un switch.
3 septembre 2011 à 23:48:56

Citation : Twistted destiny


Si pour chaque cas tu appelles une fonction différente, je vois pas ce qu'on pourrait faire de mieux qu'un switch.



Le tableau de pointeur de fonction me semble très bien, dans ce cas, non?

Citation : Twistted destiny


Mais bon c'est vachement contraignant d'avoir le même prototype pour chaque fonction.


Souvent on manipule les mêmes données dans les branches d'un même switch, donc le problème n'est pas insurmontable.

Ce sera surement plus lisible qu'un switch avec une dizaine de branchements, je pense.

Citation : Drx


Dans le post cité plus haut, on m'a gentilment proposé le bûcher (je veux des cendres) lorsque j'ai écrit qu'il était assez difficile de respecter la règle des 50 lignes


C'est pour rire, hein! :D
Zeste de Savoir, le site qui en a dans le citron !
3 septembre 2011 à 23:53:50

Citation : Twisted Destiny

Dans ce cas là autant utilisé un tableau de pointeurs sur fonction, et on appelle la fonction comme ça non: tab[lettre-'a']()?


Pas forcément, parce que déjà tu n'es pas sûr que tous les caractères se suivent (bon, ok, je pense qu'on aura pas ce souci) et s'il veut rajouter d'autres valeurs pour son switch, il pourra. :)
3 septembre 2011 à 23:57:44

Et faire un tableau, ça ne rend pas le code plus facile à maintenir (même si ça n’est pas plus difficile non plus), or c’est ça le but de ce genre de règles.

En général, je n’aime pas trop les règles sur le nombre de lignes dans une fonction. J’ai l’impression que ça tend plutôt à forcer à écrire du code stupide pour respecter la règle qu’à forcer à découper de manière plus intelligente les fonction. Si tu as besoin d’une fonction qui, par exemple, convertit les codes de touche de la bibliothèque du système vers des codes identiques pour toutes les plateformes (ce que font les bibiliothèque comme la SDL), utiliser un gros switch avec juste des case SYS_FOO: return SDL_FOO; est tout à fait légitime (bon, c’est pas comme ça qui fait la SDL, mais il y a des switchs avec du code plus compliqué pour chaque type d’événement, ce qu’on pourrait considérer comme pire… et ça fait plus que 50 lignes :D ).

Par contre, je me fixe une limite sur le nombre de caractères par ligne (en tout cas en général ; difficile de rester à 80 colonnes quand le nom d’une méthode est déjà plus long…).
4 septembre 2011 à 1:23:05

salut,
merci pour les infos, mais en fait les notions dont vous me parlez m'échappent pour le moment, je vais allez potasser le tuto de uknow sur les pointeurs de fonctions pour voir si je m'en sort avec ça.
Bon, après je dis fonction, mais ça pourrait être une fonction pour a et une addition pour b...et parfois des tests supplémentaires.

Citation : GurneyH


Citation : drx


Dans le post cité plus haut, on m'a gentilment proposé le bûcher (je veux des cendres) lorsque j'ai écrit qu'il était assez difficile de respecter la règle des 50 lignes


C'est pour rire, hein!


Oui, je m'en doute bien, sinon je ne serais plus très frais vu qu'avant de me faire frire, je me suis déjà fais snipé (ou était-ce une grenade ?) par SofEvan puis découpé par d'autres :lol:

Toujours est-il que je vous remercie, je vais aller me remplir la tête avec (encore) une nouvelle notion...

edit : je laisse le topic ouvert jusqu'à ce que j'ai fini d'assimiler le tuto au cas où il me viendrai des questions...
Nouveaux Modules pour la CEV_lib : éditeur de map (tiles) + météo. Testez le rendu ici. w pour alterner météo.
Staff 4 septembre 2011 à 11:52:53

Citation : Mon ouïe


En général, je n’aime pas trop les règles sur le nombre de lignes dans une fonction. J’ai l’impression que ça tend plutôt à forcer à écrire du code stupide pour respecter la règle qu’à forcer à découper de manière plus intelligente les fonction.



Le découpage que fera un débutant a toutes ses chances de ne pas être pertinent, ceci peu importe les contraintes qu'on lui a fixées :) .

Les bonnes habitudes c'est en apprenant qu'il faut les atteindre, après ça peut être foutu. Ils feront sans doute des découpages à la con, mais au moins ils auront les réflexes de contrôler la taille de leurs fonctions.

Pour tout dire, dans un cas d'énumération (notamment avec un switch) je me permets de déborder sur la règle de la fonction courte. Car tout simplement je considère que même si la fonction est longue, ça ne nuit pas à sa lecture. De plus si ça peut éviter de déclarer une fonction additionnelle avec comme seule justification "c'est pour que la fonction untelle ne soit pas longue" c'est, à mon gout, justifié.
4 septembre 2011 à 19:36:52

Bof bof.
J'ai toujours trouvé les conseils « fonctions de moins de 50 lignes » ridicules…

Pourquoi ?
Déjà car ce sont des limites arbitraires qui varient en fonction des gens. Certains prônent pour 30 lignes, d'autres 50, d'autres 100… Et ce sans aucune justification logique. Pourquoi ces nombres en particulier ?

Les fonctions sont censés être des opérations élémentaires qui seront en général réutilisés. Découper à mort les fonctions réduisent la lisibilité et les possibilités (avec une seule valeur de retour, les possibilités sont réduites, utiliser des pointeurs quand c'est dispensable pour combler ce manque est un exemple typique du manque de lisibilité qu'une telle solution peut apporter).

Vouloir des fonctions courtes, c'est bien, mais fixer des limites très basses qu'on ne peut dépasser est contre productif. Personnellement je me repère très bien dans des fonctions de plus de 100 lignes où il faut scroller (des fonctions que je n'ai pas écrites évidemment) du temps que c'est logique est bien écrit. Mettre sous forme de petites fonctions auraient pu réduire la lisibilité (dans le cas d'un fichier un peu grand, naviguer à la recherche de ce que fait une fonction peut être très pénible).

Bref, pour moi il faut faire le plus petit possible du temps que c'est utile et que ça apporte de la lisibilité. Créer des fonctions pour créer des fonctions est ridicule à mon goût. D'ailleurs beaucoup de gros projets écrits par des mains plus expérimentés (typiquement le noyau Linux) ne respectent pas ces soient disant règles d'or…
Je soutiens activement le projet Fedora.
4 septembre 2011 à 19:58:48

Citation : Renault

(typiquement le noyau Linux)



Ah ? Bon, j’ai jamais regardé le code, mais ils demandent pourtant d’avoir au plus 24 lignes (http://www.kernel.org/doc/Documentation/CodingStyle, section 6), même si la limite n’est pas imposée aussi strictement selon la complexité du code.

EDIT: En passant, 50 ou 100 lignes ce sont presque des limites raisonnables pour la plupart des cas. Je viens de voir des gens suggérer 5 (en Ruby) :D
4 septembre 2011 à 20:54:59

Ce ne sont que des recommandations, car pour avoir étudié pas mal de fichiers, c'est loin d'être respecté partout. ;)
De plus, si j'ai bien lu, ils conseillent entre 1 à 2 pages de 24 lignes soit 48… Puis ce n'est pas pour ça qu'ils refusent du code de toute façon. Cela dépend de la complexité et de ce qu'il fait.
Je soutiens activement le projet Fedora.
4 septembre 2011 à 21:32:24

Salut,

Citation : Renault


Déjà car ce sont des limites arbitraires qui varient en fonction des gens. Certains prônent pour 30 lignes, d'autres 50, d'autres 100… Et ce sans aucune justification logique. Pourquoi ces nombres en particulier ?



Les limites trouvent leur origine dans la résolution des terminaux de l'époque (80x24 caractères). Après, ce n'est qu'une adaptation aux nouvelles possibilités offertes par les interfaces graphiques ;)

Sinon, je suis assez du même avis, essayer de faire de petites fonctions oui, mais le découpage doit rester logique.
6 septembre 2011 à 3:09:12

re,
je suis ok sur le tuto de uknow, j'ai pigé le principe, pas complètement enregistré, mais j'arriverai à l'appliquer avec le tuto sous les yeux : Pas facile de trouver des moyens de l'appliquer pour se faire la main dessus.

Par contre, je n'ai pas pigé le truc sur l'index tu tableau :

Citation : Twisted Destiny

tab[lettre-'a']()



c'est une sorte de bind ?
Parce que si c'est juste pour la valeur, ça m'obligerait à faire un tableau de...120 ('z' ou presque...connais pas les valeurs par coeur) qui ne serait rempli qu'à partir de l'index 96 ('a' ou presque :euh: )

un truc m'échappe ?
Nouveaux Modules pour la CEV_lib : éditeur de map (tiles) + météo. Testez le rendu ici. w pour alterner météo.
6 septembre 2011 à 6:22:38

C'est juste pour déterminer l'indice du tableau de pointeurs de fonctions :-°

lettre = 'c';
printf("Indice: %d\n", lettre - 'a');


Indice: 2


d'où

tableauFonction[lettre - 'a']();


Voilà :p
6 septembre 2011 à 12:59:39

Citation : drx

Par contre, je n'ai pas pigé le truc sur l'index tu tableau :

Citation : Twisted Destiny

tab[lettre-'a']()


c'est une sorte de bind ?
Parce que si c'est juste pour la valeur, ça m'obligerait à faire un tableau de...120 ('z' ou presque...connais pas les valeurs par coeur) qui ne serait rempli qu'à partir de l'index 96 ('a' ou presque :euh: )

un truc m'échappe ?


Justement, " lettre -'a' " permet de ne pas faire un tableau de 120 ou presque, mais seulement un tableau comportant autant de cases que de lettres de l'alphabet (si tu veux aller de a à z).
En effet, si ta lettre est 'a', donc la première : " 'a' - 'a' = 0 " ! du coup, la lettre 'a' correspond à la première case du tableau, et non à la 96 (ou presque...).

Dans l'exemple de moins1, la lettre 'c' se retrouve donc à l'indice 2, puisque c'est la troisième lettre de l'alphabet !
6 septembre 2011 à 19:30:26

re,
ha ouais...mais en fait, je ne sais pas pourquoi, , je me suis imaginé un truc super complexe, en fait oui, c'est basique et ça tombe sous le sens...

Citation : uknow


ça ne doit pas être très portable tout ça.



bin déjà si ça fonctionne chez moi pour l'instant...Pis de toute façon j'aime pas les gens qui ont des Mac ;) (<- bien évidemment je rigole là)

Si je résume, on fait des fonctions de base assez courtes tant que possible, si ça ne semble pas possible on fait en sorte que ce soit suffisamment lisible. En gros : oui, mais pas trop.

merci...
Nouveaux Modules pour la CEV_lib : éditeur de map (tiles) + météo. Testez le rendu ici. w pour alterner météo.
6 septembre 2011 à 19:34:21

Citation : drx

Pis de toute façon j'aime pas les gens qui ont des Mac


Aucun rapport... :-°
Si tu prends un pc IBM, tu peux avoir des surprises, un mac non. :-°

Fonctions sur 50 lignes max ?

× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
  • Editeur
  • Markdown