IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Débats sur le développement - Le Best Of Discussion :

[Débat] Fonctions courtes ou longues ?


Sujet :

Débats sur le développement - Le Best Of

  1. #1
    Invité
    Invité(e)
    Par défaut [Débat] Fonctions courtes ou longues ?
    Bonjour.

    Je crée ce sujet pour poursuivre une digression qui a eu lieu dans les commentaires de la news sur les commentaires dans un code source.

    Celle-ci portait sur la comparaison entre :
    • un code découpé en plusieurs fonctions séparées dans des modules/classes distinctes,
    • et ce même code laissé en un seul morceau.


    Pour rappel, voici les interventions des protagonistes :

    Sérieusement, ce qui peut être fautif dans le principe général : "aucune méthode de plus de N lignes", ce ne sont pas les cycles qu'on va perdre mais le fait que 70 lignes de code, s'exécutant de manière séquentielle, dans une seule fonction, sont nettement plus faciles à lire, comprendre, et débuguer que 7 méthodes "uniques mais surement réutilisables un jour, enfin peut être" de 10 lignes, éparpillées dans trois modules distincts, avec des noms qui ne sont pas forcément si évocateurs pris hors contexte.

    Et si on applique un peu trop servilement ces principes de découplage (comme avec une application trop naive du principe de responsabilité unique), on se retrouve, dès que le programme devient un peu gros, un peu ancien, avec des verrues, avec ces abominables hiérarchies de classes qui donnent l'impression d'avoir été pensées par un bègue sous acide...

    Comme beaucoup d'autres l'ont dit, un code doit rester lisible, et, veut veut pas, il est plus confortable de lire un roman qu'un programme dont vous êtes le héros...
    Plus faciles à débugger à la rigueur, plus faciles à lire et comprendre... on ne doit pas vivre dans le même monde. Quand il faut remonter 70 lignes plus haut pour voir à quelle valeur une variable a été initialisée, s'y retrouver dans 4 niveaux de if imbriqués, bref quand il faut que notre cerveau jongle avec des dizaines de symboles plutôt que quelques-uns dans une méthode courte et focalisée, j'ai du mal à voir où est le gain de lisibilité. J'ai toujours considéré comme évident que plusieurs petits problèmes bien découpés étaient plus facilement gérables qu'un gros touffu, mais c'est intéressant de voir que ce n'est pas l'avis de tout le monde.
    On ne peut être que d'accord...

    Maintenant, si le problème est simple, et que sa solution est bien découpée en un nombre pas trop important de petits morceaux explicites et faciles à comprendre, le code sera facile à comprendre et maintenir, que tu l'aies découpé en petites tranches fines, ou gardé en gros paquets séparés par des commentaires (et des initialisations locales de paramètres, et pas de if imbriqués... ce n'est pas parce qu'on code de grosses fonctions qu'on doit forcément coder illisible, ou idiot). Bref, c'est le pays joyeux des codeurs heureux, des devs gentils, c'est le paradis...

    Si maintenant, le problème, ou plutôt sa solution, est compliqué, avec toutes sortes de cas particuliers tordus, qui interréagissent, et des effets de bords - si on est dans la vraie vie, quoi - on fait comment?

    Ma sensation, c'est que le découpage en petits bouts ne rendra pas le code plus facile à comprendre. On échange un gros machin difficile, par une collection de petits machins simples, dont on ne comprend plus l'interaction (parce que si c'était facile, on serait dans le cas où le problème ne se pose pas). Et si tous ces éléments sont dispersés dans une collection de modules, et on tout un tas de propriétés que le développeur d'origine a ajouté "des fois que", ça devient vite très compliqué.

    Avec ce code délocalisé, il est également beaucoup plus facile de tout casser en ne voyant pas un effet de bord (oui je sais, quand les problèmes sont simples, et bien découpés, cela n'existe pas... mais dans le monde réel...)

    Une fois de plus, la caricature de cela, ce sont les hiérarchies de classes démentes, avec plein de petites classes qui font des petites choses minuscules, toutes très faciles à comprendre, mais qui cachent l'organisation générale du traitement effectué.

    Ce type d'organisation est séduisante: quand on commence à le lire, on a l'impression de tout comprendre, que tout est simple.... jusqu'au moment où on se demande "comment ca marche", ou "comment le faire évoluer"...

    Personnellement, dans le cas d'un traitement compliqué, je préfère nettement avoir une grosse "fonction coeur", avec une documentation éventuellement assez compliquée, et marqué en gros au dessus : "attention code tordu" pour éviter les interventions intempestives, qu'une organisation décentralisée.
    Je tiens à lancer le débat : plusieurs fonctions courtes, ou une seule fonction longue ?

    A vrai dire, ce débat a déjà une réponse définitive et totalement tranchée, basée sur des éléments totalement objectifs. Et je suis sûr que cette réponse, et ses raisons, en surprendront plus d'un.

    Mais je suis curieux de savoir ce que les membres du forum en pensent. Il me semble que la majorité d'entre vous, et surtout ceux qui font de l'OO, privilégieront le choix de plusieurs fonctions courtes.

    A vos claviers !
    Dernière modification par Invité ; 14/05/2013 à 14h01. Motif: correction du titre

  2. #2
    Invité
    Invité(e)
    Par défaut
    Il est évident que des fonctions courtes (qui tiennent sur un écran à la lecture) sont à privilégier.

    Trois raisons principales à cela:

    1) le cerveau regarde et comprend ce qu'il a sous les yeux. Comment penser à la ligne qui se trouver 5 écrans plus bas? C'est juste super compliqué. Seul le créateur de ce bazar code en serait capable. Pas facile à maintenir donc pour le collègue.

    2) les tests unitaires, vous connaissez? Tester chaque ligne de code afin de valider qu'elle fait bien ce qu'on lui demande. Une petite fonction avec des paramètres en entrée et un résultat attendu. C'est relativement simple à tester. Plus la brique est simple, plus le test unitaire l'est. A la fin on obtient un ensemble cohérent, réalisé à partir de ces éléments.

    3) réutilisation du code.


    Je crois fermement qu'aucun développeur ne peut soutenir la thèse du code à rallonge. Ou alors, c'est quelqu'un qui n'est pas un professionnel et qui code pour le plaisir.

  3. #3
    Expert éminent sénior
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    6 803
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 6 803
    Points : 32 058
    Points
    32 058
    Par défaut
    Rien n'est évident.

    La facilité à comprendre chaque élément n'a pas forcément de lien avec la capacité à comprendre l'ensemble. Si je surdécoupe comme un malade, évidemment, chaque élément sera facile à comprendre. Mais l'ensemble?

    Si un élément n'est pas destiné à être réutilisable, si il appartient naturellement au flux de traitement, si il n'est pas trop grosalors le sortir me parait contre-productif. Et, on peut arriver, dans certains cas, à des listes longues.

    Ca n'est pas le cas le plus fréquent. Mais encapsuler les mouches, très peu pour moi.
    Les 4 règles d'airain du développement informatique sont, d'après Michael C. Kasten :
    1)on ne peut pas établir un chiffrage tant qu'on a pas finalisé la conception
    2)on ne peut pas finaliser la conception tant qu'on a pas complètement compris toutes les exigences
    3)le temps de comprendre toutes les exigences, le projet est terminé
    4)le temps de terminer le projet, les exigences ont changé
    Et le serment de non-allégiance :
    Je promets de n’exclure aucune idée sur la base de sa source mais de donner toute la considération nécessaire aux idées de toutes les écoles ou lignes de pensées afin de trouver celle qui est la mieux adaptée à une situation donnée.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Février 2004
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 47
    Points : 63
    Points
    63
    Par défaut
    On peut aussi réduire le nb de lignes de certaines fonctions en mettant les boucles qui font des petits traitements sur une seule ligne

    Quasiment tous ceux à qui je dis ça me prennent pour un fou, et pourtant ... ça améliore nettement la lisibilité globale de la fonction (on voit plus de code d'un seul coup d'œil).

    En fait il n'y a pas de règle absolue , ça dépend de la manière dont le cerveau de chacun fonctionne.
    Moi je préfère une grande fonction même tarabiscotée à pleins d'appels de classes en cascade avec 3 lignes à chaque fois car ma mémoire de pile est très limitée (je perd facilement le contexte).

    En revanche j'ai horreur du code copié collé 3 fois pour faire le même traitement, j'aime bien factoriser.

  5. #5
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 119
    Points
    28 119
    Par défaut
    Reponse de normand (que je ne suis pas) : ca depend. Et non, ce n'est pas du tout tranche.


    Pour des fonctionnalites pas trop longues, ou qui demandent un traitement particulier, le decoupage en fonctions est a privilegier. Ainsi, tu peux avoir une fonction d'initialisation, qui va etre decoupee en sous-fonctions comme "lire la conf", "traiter la conf", "initialiser les communications", etc...

    Par contre, pour une fonctionalite indivisible du genre "traiter la conf", je ne vois pas l'interet de faire une fonction "je traite le parametre A", puis "je traite le parametre B differemment", puis ainsi de suite.
    Je ne vois vraiment pas l'interet du code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int ma_fonction (parametres)
    {
       blabla;
       traitement_1 (blabla);
      blable;
      traitement_2 (blable);
      blabli;
      traitement_3 (blabli)
    Et je lui prefere une seule fonction sans sous-fonctions.

    Quant a l'argument de l'affichage sur un ecran, je crains qu'il ne faille que vous changiez d'editeurs pour passer sur des outils plus puissants (vim, emacs, eclipse, netbeans, ce que vous voulez) : la plupart proposent de "plier" des parties de code, et de se promener facilement dans le code. Donc les fonctions de moins de 50 lignes, faut un peu oublier.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 025
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 025
    Points : 5 462
    Points
    5 462
    Par défaut
    Il parait que ce n'est pas la taille qui compte, mais la façon de l'on s'en sert.

  7. #7
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Je ne vois vraiment pas l'interet du code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int ma_fonction (parametres)
    {
       blabla;
       traitement_1 (blabla);
      blable;
      traitement_2 (blable);
      blabli;
      traitement_3 (blabli)
    Et je lui prefere une seule fonction sans sous-fonctions.
    ça dépend, si le traitement_1 fait 10 000 lignes, on sera bien content d'avoir des sous-fonctions .

    Citation Envoyé par gangsoleil Voir le message
    Quant a l'argument de l'affichage sur un ecran, je crains qu'il ne faille que vous changiez d'editeurs pour passer sur des outils plus puissants (vim, emacs, eclipse, netbeans, ce que vous voulez) : la plupart proposent de "plier" des parties de code, et de se promener facilement dans le code. Donc les fonctions de moins de 50 lignes, faut un peu oublier.
    Si on "plie" le code, on a alors plus tout le code sous les yeux.

    Il faut aussi se mettre d'accord sur les "fonctions courtes" ou les "fonctions longue", pour moi les "fonctions courtes" auraient 4-5 lignes maximums et les "fonctions longues" auraient une petite 100ène de lignes maximums.

    Personnellement, je pense qu'il faut que le découpage soit cohérent, et que le code pouvant être réutilisé doit être dans une fonction.

    Si j'ai une fonctions de 3-4 lignes que je réutilise souvent ça me va, mais si je ne l'utilise qu'une seule fois, je pourrais alors peut-être directement copier-coller son code dans la fonction qui l'appelle.

    Pour les fonctions "longues", généralement, je n'arrive jamais à faire plus de 50 lignes (qui tiennent aisément sur mon écran).
    Si on respecte correctement les principes d'encapsulations et de responsabilité unique, si on découpe les fonctions de manières cohérentes, les fonctions de plus de 50 lignes sont assez rares.
    Si on a une très grosse fonction, on peut alors se demander s'il est cohérent de la découper, si une action qui est faite à l'intérieur pourrait être réutilisée, si j'enlève un bout de code pour en faire une fonction, est-ce que mon code devient plus lisible ?

    Bref pour moi c'est un peu du cas par cas donc il n'y a pas vraiment de réponses à ce débat, c'est surtout une question de dosage.

  8. #8
    Invité
    Invité(e)
    Par défaut
    capacité à comprendre l'ensemble. Si je surdécoupe comme un malade, évidemment, chaque élément sera facile à comprendre. Mais l'ensemble?
    Il faut dans ce cas lire la documentation technique associée: diagramme de flux, analyse technique...

    Si un élément n'est pas destiné à être réutilisable
    Bien malin celui qui peut prédire l'avenir d'un projet.

    Mais encapsuler les mouches, très peu pour moi.
    Encapsulateur de mouche...
    Il faut bien sûr rester raisonnable. En général, une fonction = une action. C'est très bien ainsi.

    Diviser pour mieux régner... qu'il disait...

  9. #9
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2011
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2011
    Messages : 366
    Points : 1 361
    Points
    1 361
    Par défaut
    Ce que je constate pour ma part, c'est que si l'on découpe beaucoup, on a des petites fonctions avec 3, 4, 5 paramètres, voire plus encore. Et ça devient compliqué de savoir quel paramètre sert à quoi et qui fait quoi. Une grosse fonction, genre une factory, qui prend un ou deux paramètres et qui se démerde, ça peut être bien aussi.

    Bref, ceci posé, je suis d'accord avec Gangsoleil au mot près...

    Je rajouterais que dans mon équipe, on fait des revues de code systématiquement. C'est ça qui nous permet de savoir si le code est bon, s'il est lisible, s'il est clair. Après, au fil du temps, l'oeil extérieur permet d'affiner son style, de faire simple. Le plus important, d'ailleurs, dans ce débat, c'est faire simple. Faire des longues méthodes ou des courtes, c'est un moyen, mais pas une fin. Bref, une fois de plus, KISS!!!!
    les raisonnables ont duré, les passionné-e-s ont vécu

  10. #10
    Expert éminent sénior
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    6 803
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 6 803
    Points : 32 058
    Points
    32 058
    Par défaut
    Citation Envoyé par Neukoln Voir le message
    Il faut dans ce cas lire la documentation technique associée: diagramme de flux, analyse technique...
    Quand y'en a pas? Ou, plus prosaiquement, quand on a pas le temps?

    Mon boulot, là, maintenant, que j'interrompt pour une petite pause DVP, c'est de trouver d'ou viennent 500 fichiers, sous quel format, et avec quel critère de tri. On va faire des modifications techniques massives, et il faut paramétrer l'outillage de comparaison avant/après.

    Je ne vais pas me taper 500 fois la documentation. Par contre, une petite recherche sur la création de fichier, on remonte un peu, et hop, comme le code est lisible, je sais d'ou ça vient.

    Mais si tout est méga-encapsulé avec 50 sauts pour remonter au tri(manuel ou par order by, ça dépend), je m'arrache les cheveux.

    Citation Envoyé par Neukoln Voir le message
    Bien malin celui qui peut prédire l'avenir d'un projet.
    YANGNI. tant que tu n'en as pas besoin, tu ne le créées pas. Si tu SAIS que tu vas avoir besoin, tu le créées. Si ça a un sens comme bloc isolé, tu le créées. Mais si tu ne sais pas si tu vas en avoir besoin, si ça n'est pas un bloc "naturel", alors c'est de la torture pour le mainteneur de dans 10 ans de faire une fonction exprès.



    Je maintiens du code qui a 10 à 40 ans d'âge. Les docs servent, au mieux, à savoir ou chercher. Elles sont toujours obsolètes. Elles sont souvent seulement disponible au format papier. Dans le cas idéal ou elles sont à peu près à jour, et sous forme electronique, il reste largement plus rapide de parcourir le code que de se palucher la doc. Souvent, je dois, rapidement, trouver une aiguille dans une botte de foin. Eh bien l'expérience m'a appris à chercher dans le code d'abord, et seulement dans la doc si je n'ai rien trouvé. Parceque c'est bien plus efficace.
    Les 4 règles d'airain du développement informatique sont, d'après Michael C. Kasten :
    1)on ne peut pas établir un chiffrage tant qu'on a pas finalisé la conception
    2)on ne peut pas finaliser la conception tant qu'on a pas complètement compris toutes les exigences
    3)le temps de comprendre toutes les exigences, le projet est terminé
    4)le temps de terminer le projet, les exigences ont changé
    Et le serment de non-allégiance :
    Je promets de n’exclure aucune idée sur la base de sa source mais de donner toute la considération nécessaire aux idées de toutes les écoles ou lignes de pensées afin de trouver celle qui est la mieux adaptée à une situation donnée.

  11. #11
    Invité
    Invité(e)
    Par défaut
    Je maintiens du code qui a 10 à 40 ans d'âge. Les docs servent, au mieux, à savoir ou chercher. Elles sont toujours obsolètes
    Oui, c'est vrai aussi. Je rencontre ce cas là.
    C'est d'ailleurs dans un projet VB6 que les développeurs qui bossent avec moi s'arrachent les cheveux sur des fonctions qui font plusieurs milliers de lignes.

  12. #12
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Perso, je ne m'impose aucune règle du style "max n lignes", pourtant mes fonctions ne dépassent que rarement une page à l'écran.

    Quant à factoriser en plusieurs méthodes, on peut le faire pour plusieurs raisons, par exemple limiter les variables locales dans le scope (y'a rien de pire que les fonctions monoblocs qui font 5 traitements avec chacune plusieurs variables à usage perso) et surtout décrire le flux.

    Si vous arrivez à découper un traitement en fonction comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    decimal fraisDePort;
    
    if( dansZoneEu( commande.adresse.codePays ) ) {
        fraisDePort = tarifExpedition( commande.poidsTotal, commande.transporteur, ZONE_1)
    } else {
        fraisDePort = tarifExpedition( commande.poidsTotal, commande.transporteur, ZONE_2);
        fraisDePort += calculeDroitDouane(commande.listeProduit); 
    }
    
    if( soumisTva( commande.listeProduit )  ) {
    
        fraisDePort = calculeTva(  mtFraisPort )
    }
    C'est un peu trivial mais la factorisation documente le traitement lui-même, si vous empiliez tout, même si la plupart des fonctions devaient ne pas être réutilisable, ce serait moins évident de comprendre la logique appliquée.

    Donc pour moi, découper le code en plusieurs méthodes même si ce n'est pas toujours réutilisables, je dis oui pour les cas suivants :

    • Si ça rend la logique du traitement plus simple
    • Si ça facilite les tests automatisés
    • Si c'est objectivement réutilisable (faut pas bosser juste pour bosser)


    Quant à s'imposer de le faire après n lignes pour obéir à une règle, ça c'est être dogmatique, c'est jamais bien dans ce métier de s'imposer un absolu.

  13. #13
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    418
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 418
    Points : 828
    Points
    828
    Par défaut Mes 2 pences
    J'ai tendance à découpler également en petites fonctions principalement pour la lisibilité :
    Lorsqu'on a un gros traitement à faire, qu'on le découpe en fonctions correspondant à des étapes de traitement cohérentes et que le nom des fonctions est bien choisi, alors la lecture de la fonction principale (qui appelle toutes les autres) donne l'algorithme général du traitement.
    Cet aspect n'est pas anodin quand on doit reprendre certains traitement développés par un type parti depuis plusieurs années.
    Cet algo peut être écrit sous forme de commentaire mais c'est moins bien car les commentaires sont beaucoup moins précis pour définir le début et la fin d'un traitement...

    Contrairement à ce que dit gangsoleil, je trouve ça infiniment plus facile à lire :
    La fonction principale donne les étapes importantes du traitement : on ne se perd pas à examiner les plinthes alors qu'on ne sait même pas combien d'étages à la maison.

    Et puis chaque étape est clairement dégagée, les portées des variables sont clairement définies...

    Les retours d'expériences que j'ai eu m'ont largement démontré que le code éclaté est plus facile à appréhender pour quelqu'un qui doit reprendre un programme. C'est aussi moins sujet aux bugs car cela demande un effort d'organisation et de gestion des variables.

    Cela dit, il y a quand même un aspect qui fait que toutes ces considérations restent sujettes à caution, c'est que cela demande à ce que le découpage soit bien fait.
    Mieux vaut un code monolithique et soigné qu'un code éclaté n'importe comment.

  14. #14
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 119
    Points
    28 119
    Par défaut
    Citation Envoyé par fatbob Voir le message
    Lorsqu'on a un gros traitement à faire, qu'on le découpe en fonctions correspondant à des étapes de traitement cohérentes et que le nom des fonctions est bien choisi, alors la lecture de la fonction principale (qui appelle toutes les autres) donne l'algorithme général du traitement.

    La fonction principale donne les étapes importantes du traitement : on ne se perd pas à examiner les plinthes alors qu'on ne sait même pas combien d'étages à la maison.
    Ceci n'est lisible que si tu gardes un unique niveau d'appel. Des que tu as des fonctions qui en appellent d'autres qui en appellent d'autres qui en appellent d'autres, tu te retrouves vite perdu a ne plus savoir d'ou tu viens.


    Mieux vaut un code monolithique et soigné qu'un code éclaté n'importe comment.
    Je dirai meme plus : eclate ou monolithique, mieux vaut un code soigne que n'importe quelle autre bouse.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  15. #15
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Ceci n'est lisible que si tu gardes un unique niveau d'appel. Des que tu as des fonctions qui en appellent d'autres qui en appellent d'autres qui en appellent d'autres, tu te retrouves vite perdu a ne plus savoir d'ou tu viens.
    Si les divisions sont faite avec les principes d'encapsulation/abstraction, je ne vois pas trop le problème.
    On peut utiliser la fonction strtol() par exemple, cette dernière appelle peut être 50 fonctions avec 20 niveau d'appels ou bien n'appelle aucune fonction. Cela nous dérange pas de savoir de quelle façon elle est implémentée pour l'utiliser.

    Le tout est que plus on descent dans les niveaux d'appels, plus on doit rentrer des les détails.
    Les niveaux supérieurs doivent servir d'abstractions aux niveaux inférieurs, de cette façon la lecture du code est simplifié et on entre progressivement dans les détails.

  16. #16
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    418
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 418
    Points : 828
    Points
    828
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Ceci n'est lisible que si tu gardes un unique niveau d'appel. Des que tu as des fonctions qui en appellent d'autres qui en appellent d'autres qui en appellent d'autres, tu te retrouves vite perdu a ne plus savoir d'ou tu viens.
    Pas forcément...
    Mais cela rejoint l'autre remarque.
    Si on fait des fonctions pour faire des fonctions, si possible avec des noms en léger décalage avec le traitement qu'elles réalisent, alors mon raisonnement ne tient évidemment pas.
    Par contre, si c'est fait correctement, la lecture est aisée.
    D'autant que beaucoup d'outils permettent d'ouvrir facilement les fonctions appelées.

  17. #17
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    418
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 418
    Points : 828
    Points
    828
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Si les divisions sont faite avec les principes d'encapsulation/abstraction, je ne vois pas trop le problème.
    On peut utiliser la fonction strtol() par exemple, cette dernière appelle peut être 50 fonctions avec 20 niveau d'appels ou bien n'appelle aucune fonction. Cela nous dérange pas de savoir de quelle façon elle est implémentée pour l'utiliser.

    Le tout est que plus on descent dans les niveaux d'appels, plus on doit rentrer des les détails.
    Les niveaux supérieurs doivent servir d'abstractions aux niveaux inférieurs, de cette façon la lecture du code est simplifié et on entre progressivement dans les détails.
    +1

  18. #18
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 119
    Points
    28 119
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Les niveaux supérieurs doivent servir d'abstractions aux niveaux inférieurs, de cette façon la lecture du code est simplifié et on entre progressivement dans les détails.
    Si tu peux garder ces differents niveaux d'abstraction, c'est valable. Mais dans les gros projets, tu te rends vite compte que ces niveaux d'abstraction sont difficiles a garder, et que tout le monde a besoin d'acceder a un peu tout, mais pas tout non plus...

    Donc tu te retrouves a lire du code en devant suivre les differents niveaux d'appels, puis a revenir, puis a repartir, ...

    Dans ce cas, je ne vois vraiment pas d'interet au decoupage.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  19. #19
    Membre éclairé

    Inscrit en
    Novembre 2008
    Messages
    418
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 418
    Points : 828
    Points
    828
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Si tu peux garder ces differents niveaux d'abstraction, c'est valable. Mais dans les gros projets, tu te rends vite compte que ces niveaux d'abstraction sont difficiles a garder, et que tout le monde a besoin d'acceder a un peu tout, mais pas tout non plus...

    Donc tu te retrouves a lire du code en devant suivre les differents niveaux d'appels, puis a revenir, puis a repartir, ...

    Dans ce cas, je ne vois vraiment pas d'interet au decoupage.
    Nous ne devons pas lire le code de la même façon :-)
    Pour ma part, je préfère largement avoir un premier aperçu d'ensemble de ce que fait le traitement puis, si le besoin s'en fait sentir, de descendre dans les détails utiles.
    En cas de maintenance ou d'évolution, les interventions sont le plus souvent localisées à quelques endroits qui seront plus facile à identifier à partir d'une fonction "table des matières" qu'en devant se palucher tout le roman.
    Paradoxalement, je pense que tu fais beaucoup plus d'allers et retours dans un gros pavé monolithique que dans un code éclaté intelligemment. J'insiste sur ce mot parce qu'il est évident que c'est la condition indispensable pour que l'éclatement présente de l'intérêt.

    L'idée est, dans le cas de traitements dont on voit bien qu'ils seront gros, de bien repérer les ensembles fonctionnellement élémentaires et de les extraire en fonctions séparées pour qu'il soit mieux rangé.

    Encore une fois, il ne s'agit pas de découper n'importe quoi n'importe comment : je rejoins _skip sur l'absence d'intérêt du respect d'une taille préfixée en nombre de ligne qu'il ne faudrait jamais dépasser. Il ne s'agit pas non plus de tronçonner le code toutes les n lignes en fonctions qu'on appelle séquentiellement, ou de créer des fonctions d'une ligne pour changer le nom de la fonction.
    An final, en pratique, je me retrouve très rarement avec 36 niveaux d'appels imbriqués, surtout dans le cas de gros traitements "séquentiels".

    Et (juste en passant) la remarque sur les gros projets est non recevable. C'est l'argument qui est servi à chaque fois qu'on veut donner du poids à son argumentation. Je pense que beaucoup des intervenants, ici, sont déjà intervenu sur ces "gros projets". Et des gros projets, il y en a des bien développés et il y en a des super crassoux. Le fait qu'un projet soit gros ne signifie en aucun cas qu'il a été bien développé.
    Pour ce qui me concerne, j'ai commencé par une bonne dizaine d'années en SSII sur des projets de dev de 2-3 ans pour 5 à 10 développeurs. Je pense donc avoir une idée de ce que c'est et j'ai eu le temps de me rendre compte de l'intérêt de différentes organisations de code (c'est pas toujours moi qui décide).
    Sans considérer que mon choix est le seul qui vaille, je trouve que les gros blocs monolithiques sont désagréables à lire car on est obligé de faire attention à des centaines de lignes même si l'on veut n'en modifier que deux (en particulier à cause des portées de variables).

    Et pour ce qui est de la difficulté à garder une ligne de conduite en développement en équipe, le fait est, c'est que si les normes de développement utilisées pour un projet sont simples, intuitives et apportent un réel intérêt pour les développeurs, elles sont mises en oeuvre. Sinon, elles ne le sont pas.

  20. #20
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par mewtow Voir le message
    A vrai dire, ce débat a déjà une réponse définitive et totalement tranchée, basée sur des éléments totalement objectifs. Et je suis sûr que cette réponse, et ses raisons, en surprendront plus d'un.
    Ah oui ??

    On aimerait bien la connaitre

    J'en ris d'avance...

    Comme l'ont dit mes collègues ci-dessous :

    Citation Envoyé par el_slapper Voir le message
    Rien n'est évident.

    La facilité à comprendre chaque élément n'a pas forcément de lien avec la capacité à comprendre l'ensemble. Si je surdécoupe comme un malade, évidemment, chaque élément sera facile à comprendre. Mais l'ensemble?

    Si un élément n'est pas destiné à être réutilisable, si il appartient naturellement au flux de traitement, si il n'est pas trop grosalors le sortir me parait contre-productif. Et, on peut arriver, dans certains cas, à des listes longues.

    Ca n'est pas le cas le plus fréquent. Mais encapsuler les mouches, très peu pour moi.
    Citation Envoyé par gangsoleil Voir le message
    Reponse de normand (que je ne suis pas) : ca depend. Et non, ce n'est pas du tout tranche.

    D'une part les soi-disant "normes" sont absudes si elles sont suivies au pied de la lettre. Arrêter ou découper une fonction parce qu'elle fait 70 lignes et non pas 50 est absurde en soi..

    D'autre part, dans certains cas il vaut mieux une grosse fonction que 200 petites, même si la fonction fait 2000 lignes... C'est très rare, mais ça existe.

    J'en ai fait 2 dans un gros soft. J'étais pas content, mais je voyais pas comment faire autrement..


    Ce qu'il faut bien comprendre, c'est qu'il y a 4 choses à prendre en compte : la lisibilité gloobale, la lisbilité à petite échelle, l'efficacité, et l'overhead.

    • Chaque appel de fonction c'est des paramètres dans une pile, et la copie de ces paramètres.

    • Plus il y a d'appels, plus il y a de possibilité d'être "unloadé" temporairement par le loader, et d'avoir à "recharger" la fonction plus tard.

    • Plus il y a d'appels, plus il faut éventuellement avoir des paramètres différents dans la fonction appelante

    • Enfin, pour le débogage et la compréhensiion, si un traitement a besoin de 150 choses // , certaines pouvant se modifier en cours e route par des interventions extérieures, il est plus aisé et compréhensible d'avoir des appels d'eventuelles mises à jour - et donc éventuellement recalculs ou re-fabrications/changements de buffers - que des varaibles globales, des "exceptions" arrivant on ne sait quand et localisées on ne sait où dans le code..



    • Le nombre d'appels de fonctions est essentiel dès qu'on touche à de l'efficacité.
    • Le dernier point est essentiel pour la compréhension, débogage, et sûreté du soft


    Je ne vois donc pas comment on pourrait tirer une conclusion.. On peut tendre vers une certaine limitation. En dehors de ça, c'est absurde..



    Citation Envoyé par fatbob Voir le message
    Et (juste en passant) la remarque sur les gros projets est non recevable. C'est l'argument qui est servi à chaque fois qu'on veut donner du poids à son argumentation. Je pense que beaucoup des intervenants, ici, sont déjà intervenu sur ces "gros projets". Et des gros projets, il y en a des bien développés et il y en a des super crassoux. Le fait qu'un projet soit gros ne signifie en aucun cas qu'il a été bien développé.
    .
    Oui, mais ça n'est pas lié à la taille des fonctions.

    Par contre, ce qu'on peut affirmer, c'est que si sur un gros projet de plusieurs millions de lignes, chaque fonction est limitée à 20 lignes, ça sera totalement non maintenable et inbitable..

    Et si en plus on fait une fonction par fichier (ce qui ressemble très fort à ce qui se fait avec les méthodes basées sur l'OO et les classes) , ce qui est recommandé par certaines normes, alors là c'est la catastrophe assurée..

    On a déjà du mal à s'y retrouver avec 100 fichiers de 100 fonctions et de 5000 lignes chacun, mais bien identifiés par fonctionalité, si c'est 10000 fichiers c'est plus la peine d'essayer de s'y retrouver..
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

Discussions similaires

  1. [XL-2003] Fonctions SI trop longue
    Par makila64 dans le forum Excel
    Réponses: 7
    Dernier message: 05/03/2012, 21h41
  2. Réponses: 1
    Dernier message: 31/05/2010, 22h01
  3. Réponses: 5
    Dernier message: 22/06/2009, 11h02
  4. [Débat] Développement à court terme ou pérenne ?
    Par souviron34 dans le forum Débats sur le développement - Le Best Of
    Réponses: 79
    Dernier message: 08/06/2009, 06h48
  5. Réponses: 4
    Dernier message: 16/03/2004, 18h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo