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. #21
    Invité
    Invité(e)
    Par défaut
    Je me permets de donner quelques éléments pour orienter le débat. Il faut savoir que la problématique a étè étudiée par des psychologues cognitifs, et plus précisément par des spécialistes de Psychology Of Programming. Pour ce faire, diverses expériences ont étés effectuées.

    Expériences

    On peut notamment citer celle effectuée par (Boehm-Davis + al., 1992). Dans celle-ci, les expérimentateurs avaient préparés 3 programmes. Chacun de ces 3 programmes était déclinés en trois versions identiques à un détail prêt :
    • un de ces 3 programmes était écrit d'une manière monolithique : un bon gros main des familles comme on en fait plus ;
    • un découpé en fonctions assez longues ;
    • un découpé en suivant les bonnes pratiques OO, avec pleins de petites fonctions partout, de l'héritage et des tas d'autres trucs dans le genre.

    Bilan : les programmes OO, avec des fonctions courtes, étaient perçus par les programmeurs comme difficiles à lire et à comprendre. Les étudiants et professionnels ayant servis de cobayes avaient aussi mis plus de temps pour effectuer divers changements dans le programme OO que dans les autres programmes (avec un gros main et des fonctions longues).

    Les études suivantes : El-Emam et al., 1999; El-Emam et al., 2001b, ont montrées que la majorité des bugs et erreurs dans une application se situaient justement aux endroits où l'on trouvait de l'export coupling. A savoir, quand un truc défini dans un module/classe est réutilisé ailleurs. Et pire : plus le chunk en question était réutilisé, pire c'était. Et les appels de fonction sont justement un cas d'export coupling.

    Autre exemple : les travaux de Wang sur les poids cognitifs de différentes structures de contrôle usuelles. Ces travaux supposent une différence de compréhension entre processus cognitif inconscients (lecture linéaire du code), méta-cognitifs (sauts simples, conditions, appels de fonctions), et processus de haut niveau (boucles, récursion, etc). La recherche sur les poids cognitifs (cognitives weight) se base sur ces concepts, et tend à montrer que les appels de fonctions auraient un poids cognitif plus élevé que la lecture linéaire de code.

    Théories

    Les raisons à cet état de fait sont dorénavant bien connues, et ont notamment étè étudiées par (Cant, al., 1995). Pour les auteurs, la compréhension d'un code source dépend de deux facteurs : le chunking, et le tracing. Commençons par le chunking.

    Chunking

    Comme vous le savez tous, notre mémoire est décomposées en plusieurs sous-mémoires : des mémoires sensorielles, des mémoires à court terme, et des mémoires à long terme. Nos mémoire à court terme ont une capacité finie : elles peuvent retenir un nombre limité de connaissances de base, des chunks. Si jamais on essaye de traiter plus d’éléments que nos mémoires à courts terme ne peuvent en contenir, les performances cognitives s'effondrent et, le taux d'erreur augmente fortement.

    Les développeurs sont soumis à ces contraintes : un code source lisible est un code source facilement découpable en chunks. Pour découper un code source, les développeurs se basent sur divers indices : découpage en paragraphe, indentation, etc ; pour reconnaitre des chunks et/ou des morceaux de code familiers.

    Pour comprendre un code, un développeur doit comprendre :
    • les chunks en eux-même ;
    • les chunks dont le chunk dépend (exemple : fonction utilisée dans un chunk), et récursivement sur ces chunks ;
    • et comment les chunks sont reliés entre eux, et les dépendances qui en suivent.


    Tracing

    Mais ce chunking du code peut être perturbé par divers effets. On peut notamment citer les effets de tracing. Le tracing, c'est quand un développeur/lecteur de texte doit interrompre sa lecture pour la reprendre à un autre endroit assez éloigné du code : dans un autre fichier, ou ailleurs. Il doit alors traverser le programme en cours pour repérer les chunks pertinents.
    Ce tracing a deux effets :
    • il impose un cognitive switch : l'attention est détournée dans un autre but, ce qui empêche le maintien du contenu des mémoires à court terme, et cause un effet d’interférence ;
    • elle donne le champ libre au fan-effect, qui nous dit que plus un chunk est associé à d'autres chunks, plus celui-ci sera difficile à comprendre ou à mémoriser ;
    • elle augmente le nombre d'associations non-inconscientes entre les chunks ;


    Plus un code est découpé en fonctions, plus celui-ci a un tracing important. Par contre, plus la lecture du code est linéaire, sans sauts, moins il y aura de tracing. L'effet sur la charge cognitive est de plus en faveur d'un code linéaire : n'oubliez pas que lire du code linéaire ne demande pas de mémoriser consciemment les associations entre morceaux de code, contrairement aux appels de fonctions qui imposent des associations méta-cognitives (cf travaux de Wang cités plus haut).

    Bilan

    Tout ces éléments vont clairement dans le sens d'un découplage entre compréhension locale d'un code source, et compréhension globale. Ce qui a étè mentionné pas pas mal d'intervenants.

    Bilan : si vous voulez écrire un code source, n'utilisez pas les fonctions pour le chunker. Un bon découpage se base plus sur le paragraphage, sur l'indentation, sur l'aspect extérieur et syntaxique du code qu'autre chose. Les fonctions courtes ne font que vendre du chunking contre du tracing. Il faut donc privilégier des fonctions assez longues, pour limiter la survenue d'effets de tracing au maximum des possibilités.

    Autres

    Pour ceux intéressés par le sujet, sachez que les fonctions ne sont pas les seules entités programmatiques qui subissent les effets du tracing. L'héritage est aussi fortement touché. Pour ceux qui s'intéresse au sujet, je recommande la lecture de l'article "Validating Object-Oriented Design Metrics on a Commercial Java Application", par Daniela Glasberg et al.

  2. #22
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2008
    Messages : 612
    Points : 1 050
    Points
    1 050
    Par défaut
    Salut
    -----

    Curieux débat que celui commençant par indiquer que de toutes façons il n'y a qu'une et une seule réponse, et que celle-ci est déjà connue.

    Mais bon...

    Ensuite, de nouveau, on assiste à une transformation d'un débat "de fond" en un débat "dans lequel le contexte est défini"

    Déjà le choix n'est pas toujours possible, il y a des tas de cibles avec un niveau d'imbrication des sous-routines limités à cause de la taille de la pile.

    Puis, pour ceux qui privilégient le scindage "ultra-court" il est "omis", volontairement ou non, un point très important. En effet, quand on crée une méthode dans un langage évolué, on a des conditions d'entrées, de sortie, et des plages admissibles pour les paramètres.

    Une méthode qu'on veut "universelle", ou, dit autrement, "récupérable", doit donc comporter des tests sur la validité des paramètres, pour ne prendre que cet exemple. Ainsi, ma méthode "Divise" doit renvoyer une erreur si on divise par 0 (cas évident).

    Si je me mets à scinder une méthode monolithique, j'obtiens plusieurs méthodes plus simples, mais, sauf si je programme n'importe comment, je suis de nouveau obligé, pour prévoir la ré-utilisation, de vérifier les paramètres passés à ces "sous-méthodes". Moralité, en scindant j'augmente la taille totale du code, donc le nombre de bugs potentiels, et également la longueur de la re-lecture.

    Il ne faut pas non plus oublier que scinder une méthode à un coût en terme de temps CPU (parfois sans importance, d'autre fois au contraire c'est très important), de consommation mémoire, de consommation de pile, etc.

    Bref, au contraire des commentaires, qui sont neutres au niveau de la machine, la scission du code ne l'est pas, elle coûte.

    Quant à la lisibilité, il n'y a pas grande différence de lisibilité de l'ensemble des opérations si le code est écrit proprement. Ajouter une méthode ne provoque une sensation de lisibilité que du fait d'un découpage visuel, qu'on peut parfaitement reproduire avec un simple commentaire.

    Pour ma part, je scinde le plus souvent par "fonctionnalité monolithique", considérant qu'il ne sert à rien d'obtenir des bouts de code qui n'exécutent pas une fonction ré-utilisable. Donc, je scinde dans l'esprit de factorisation.

    Donc, moi je dirais qu'il n'y a pas à avoir d'avis tranché. Je dirais également qu'il ne faut imposer ni une vision des choses ni son contraire. Scinder le code à bon escient est fonction du contexte, et c'est le boulot de l'informaticien de juger s'il scinde ou non, et si oui, ou et quand.

    Il faudrait arrêter cette manie de vouloir tout mettre dans des cases étiquetées, de promulguer des règles sorties de soi-disant experts, et d'empêcher les gens qui travaillent (quel que soit le secteur) de faire fonctionner leur intelligence et leur esprit critique: on n'est pas des machines... du moins pas moi.

    A+
    Claude

  3. #23
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par mewtow Voir le message
    Je me permets de donner quelques éléments pour orienter le débat. Il faut savoir que la problématique a étè étudiée par des psychologues cognitifs, et plus précisément par des spécialistes de Psychology Of Programming. Pour ce faire, diverses expériences ont étés effectuées.
    Ohhhh que c'est beau.....

    D'après ce que je lis des expérirences, ça m'étonnerait fortement qu'ils aient pris des programmes de quelques millions de lignes....

    C'est sûr que ces experts-là sont bien plus à l'aise dans la compréhension de ce qu'on fait devant un programme que des salos de bidouilleux


    Ce que j'aime surtout, c'est ce genre de bilan :

    Citation Envoyé par mewtow Voir le message
    Bilan : si vous voulez écrire un code source, n'utilisez pas les fonctions pour le chunker. Un bon découpage se base plus sur le paragraphage, sur l'indentation, sur l'aspect extérieur et syntaxique du code qu'autre chose. Les fonctions courtes ne font que vendre du chunking contre du tracing. Il faut donc privilégier des fonctions assez longues, pour limiter la survenue d'effets de tracing au maximum des possibilités.

    Tout ces pavés pour en arriver là ????

    Tu as lu ce que les gens ont mis au dessus ???

    N'importe quelle développeur ayant traîné assez longtemps sur une variété de projets, et en particulier des gros à très gros, est capable de dire que ça dépend des cas.. Et le dit..

    Il est préférentiel d'utiliser des petites fonctions bien circonscrites. Cependant le terme "petit" (ou "grand") est variable suivant 1) la taille du projet et 2) la fonctionalité.

    Maintenant, ces "limites" sont à déterminer pour chaque projet / partie de projet.. et pour chaque type d'intervenant.. et de fonctionalité...


    Mais il est évident que l'archi-découpage OO est une absurdité dès que ça devient gros, de même que le monolithisme absolu...

    Le bon sens, encore une fois, doit prévaloir...

    Savoir ce que cetains chercheurs trouvent, ça peut être intéressant.. Mais ça n'est qu'un aspect des choses....

    "Privilégier des fonctions assez longues" est autant une absurdité que son contraire...

    Il faut simplement privilégier une lecture relativement aisée ainsi qu'un débogage assez aisé..

    (un exemple de mauvaise pratique : au début des années 90 la mode était de mettre des raaccourcis d'appels de fonctions avec certains paramètres dans des define dans des .h.. Je vous raconte pas les mals de têtes pour débogeur un programme comme ça comportant 300 sources...)



    Citation Envoyé par ClaudeBg Voir le message
    Salut
    Curieux débat que celui commençant par indiquer que de toutes façons il n'y a qu'une et une seule réponse, et que celle-ci est déjà connue.
    ..
    Il faudrait arrêter cette manie de vouloir tout mettre dans des cases étiquetées, de promulguer des règles sorties de soi-disant experts, et d'empêcher les gens qui travaillent (quel que soit le secteur) de faire fonctionner leur intelligence et leur esprit critique: on n'est pas des machines... du moins pas moi.


    D'autant plus que la soi-disant conclusion plus haut est hautement discutable, et non-vérifiée par la plupart ici.. Et j'aime bien le "est démontrée"....

    Bref, un trolll...

    Je parierais presque que ce gentil posteur va nous dire qu'il fait de la programmation spontanée, et que c'est démontré comme étant la meilleure technique....

  4. #24
    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 129
    Points
    28 129
    Par défaut
    psychologues cognitifs
    On parle bien des gens qui ont chacun un avis different de leur voisin ?

    Citation Envoyé par mewtow Voir le message
    Le tracing, c'est quand un développeur/lecteur de texte doit interrompre sa lecture pour la reprendre à un autre endroit assez éloigné du code : dans un autre fichier, ou ailleurs. Il doit alors traverser le programme en cours pour repérer les chunks pertinents.
    Je rebondis juste sur ce point, qui est a mon sens revelateur de la non-pertinence de l'etude : dans la plupart des IDE modernes, une commande unique (ctrl+clic par exemple) permet immediatement d'etre bascule vers le code de la fonction que l'on veut voir, puis une autre commande (clic sur une fleche, ctrl+backspace, ...) permet de revenir immediatement a l'appel ou on etait.

    Et comme le dit Souviron34, la conclusion de type "ca depend", c'est pas glop quand meme :
    N'importe quelle développeur ayant traîné assez longtemps sur une variété de projets, et en particulier des gros à très gros, est capable de dire que ça dépend des cas.. Et le dit..

  5. #25
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Je rebondis juste sur ce point, qui est a mon sens revelateur de la non-pertinence de l'etude : dans la plupart des IDE modernes, une commande unique (ctrl+clic par exemple) permet immediatement d'etre bascule vers le code de la fonction que l'on veut voir, puis une autre commande (clic sur une fleche, ctrl+backspace, ...) permet de revenir immediatement a l'appel ou on etait.
    Ce qui n’empêche pas l’occurrence d'un cognitive switch lors de la lecture du code. Le lecteur du code doit toujours passer d'une tache à une autre, et doit utiliser un processus méta-cognitif pour cela. Que cela se fasse en un clic ou avec une procédure plus longue ne change rien.

    De plus, cela n'a aucune influence sur le fan-effect imposé par l'utilisation de fonctions, et encore moins sur les interférences en mémoire à court terme.

    Le conclusions des études mentionnées plus haut restent donc valables.

  6. #26
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par mewtow Voir le message
    Ce qui n’empêche pas l’occurrence d'un cognitive switch lors de la lecture du code. Le lecteur du code doit toujours passer d'une tache à une autre, et doit utiliser un processus méta-cognitif pour cela. Que cela se fasse en un clic ou avec une procédure plus longue ne change rien.

    De plus, cela n'a aucune influence sur le fan-effect imposé par l'utilisation de fonctions, et encore moins sur les interférences en mémoire à court terme.

    Le conclusions des études mentionnées plus haut restent donc valables.


    Tu est capable de comprendre le charabia que tu nous mets là ?? Moi non, et je suis certain que tous les autres intervemants non plus..


    Fais gaffe, trop de théorie tue la théorie

    J'adorerais avoir la définition de ce qui est "méta-cognitif"...


    Arrête de troller stp, tu pollues la bande passante...

  7. #27
    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 129
    Points
    28 129
    Par défaut
    Citation Envoyé par souviron34 Voir le message


    Tu est capable de comprendre le charabia que tu nous mets là ?? Moi non, et je suis certain que tous les autres intervemants non plus..


    Fais gaffe, trop de théorie tue la théorie

    J'adorerais avoir la définition de ce qui est "méta-cognitif"...
    J'ai pense exactement la meme chose en lisant la reponse... Et j'ai bien rigole aussi.

    Il est necessaire d'arreter d'embeter les dipteres par moment...

  8. #28
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 084
    Points
    7 084
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Je rebondis juste sur ce point, qui est a mon sens revelateur de la non-pertinence de l'etude : dans la plupart des IDE modernes, une commande unique (ctrl+clic par exemple) permet immediatement d'etre bascule vers le code de la fonction que l'on veut voir, puis une autre commande (clic sur une fleche, ctrl+backspace, ...) permet de revenir immediatement a l'appel ou on etait.
    Argument que tu avais déjà avancé avec les code collapse . On pourrait également parler de l'accès direct à la documentation de la fonction sans lire le code... Ceci dit quand je vois les dates des études, il faut pas s'étonner.

    Par ailleurs chaque appel de fonction n'a pas besoin d'être analysé. Si j'appel la fonction search(list, element), j'ai une bonne idée de ce qu'elle fait. Et avant toute "optimisation de la taille d'une fonction", il faut déjà s'intéresser à la pertinence de son nom. Et plus il y aura de fonction, plus il faudra de noms bien distincts et explicites. L'expressivité devance l'argument de la taille en ce qui concerne la relecture (déchiffrage et compréhension).

    Autre élément, la consultation d'un code source ne fait pas uniquement référence à la mémoire à court terme puisqu'elle permet également de "s'imprimer" (mémoire à plus long termes), le fonctionnement du module étudié. Chaque analyse/lecture de code/développement n'est pas un one-shot ...


    Pour ceux qui argumente sur l'exécution, il faut tout de même prendre en considération les optimisations du compilateur (y compris JIT). Tous les appels de fonction ne nécessite pas une allocation sur la pile d'appel (fonction inline) ou la recopie des arguments. Enfin les quelques millièmes de secondes perdues à l'exécution ne seront surement rien à côté des coûts en maintenance (debug, analyse, développement, etc).

  9. #29
    Membre du Club
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2009
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Congo-Kinshasa

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2009
    Messages : 38
    Points : 65
    Points
    65
    Par défaut
    J'ai suivi avec attention ce débat et je voudrais argumenter dans une direction non encore explorée.
    Beaucoup d'intervenants proposent de découper le programme (ou une fonction précise, peu importe) comme ci comme ça, comme si l'organisation et le fonctionnement de l'application sont à définir au moment de l'implémentation. Je rappelle que implémenter veut dire "mettre oeuvre", "réaliser" ce qui a déjà été spécifié et conçu et que coder fait partie de l'implémentation. La question discutée dans ce fil est plus une question de conception que de programmation. L'activité de conception, enrichie de la modélisation, permet de prendre du recul et de penser l'organisation interne de son application, avant même de commencer à taper son code. Lorsqu'on fait attention aux activités et étapes essentielles d'un développement logiciel, certaines questions se résolvent d'elles-mêmes. Ceux d'entre nous qui prennent le temps de pratiquer le minimum d'ingénierie logicielle en savent long.

  10. #30
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 91
    Points : 133
    Points
    133
    Par défaut
    C'est un avis complêtement personnel, mais bien que je sois pour la découpe, je ne veux surtout pas être catégorique.

    En effet, comprendre une fonction/méthode de 4/5 lignes, c'est simple, cela demande très peu d'effort, et c'est rapide.

    Maintenant si je prends une fonction un peu compliqué, et que j'applique la rêgle "je découpe en fonctions de moins de 5 lignes", je suis absolument sur et certain que je comprendrais moins bien à la fin qu'au début.

    La raison en est très simple. Sur une fonction de 100 lignes, je n'ai pas toute les lignes sous les yeux. Sur mon poste de travail j'en aurais environ une 50aine, sur un laptop une 30aine, c'est pas assez on est d'accord. Maintenant, si je compare avec la même fonction découpée, avec la règle ci-desus, j'aurais à chaque fois tout le code d'une fonction sous les yeux. Mais je n'aurais jamais la structure complête de la fonction sous les yeux non plus. Chaque imbriquement de tests et ou de boucles sera une nouvelle "sous-fonction", et on s'y perd très facilement.

    Il me semble que l'idée de fonction minimale était évoquée dans l'ouvrage "Coder proprement" de Robert C. Martin (http://www.developpez.net/forums/d78...bert-c-martin/), et bien que j'ai essayé d'appliquer sa philosophie d'écriture de code, il est clair que rien que l'emplacement de la déclaration des "sous-fonctions" est une question importante.

    Ou placer ses "sous-fonctions" dans le code ? Nous pouvons observer la découpe suivante (complètement accentuée pour l'argumentation) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    public static void thisFunctionIsNotShort(){
    	boolean isNotShort = true;
    	if(isNotShort){
    		for (int i = 0; i < 100; i++) {
    			boolean uselessBoolean = true;
    			System.out.println("You see that this function is not short");
    			if(uselessBoolean){
    				System.out.println("uselessBoolean is useless but prints something");
    			}
    		}
    	}
    	else{
    		for(int i = 0; i<10;i++){
    			System.out.println("This is never reached but it doesn't matter");
    		}
    	}
    }
    
    //-----------------------------------------------------------------------//
    
    
    public static void thisFunctionIsShort(){
    	boolean isNotShort = true;
    	if(isNotShort)
    		handleNotShortFunction();
    	else
    		handleShortFunction();
    }
    
    public static void handleNotShortFunction(){
    	for (int i = 0; i < 100; i++) {
    		printOutputFromShortFunction();
    	}
    }
    
    public static void handleShortFunction(){
    	for (int i = 0; i < 10; i++) {
    		System.out.println("This is never reached but it doesn't matter");
    	}
    }
    
    public static void printOutputFromShortFunction(){
    	boolean uselessBoolean = true;
    	System.out.println("You see that this function is not short");
    	handleUselessBoolean(uselessBoolean);
    }
    
    public static void handleUselessBoolean(boolean uselessBoolean){
    	if(uselessBoolean){
    		System.out.println("uselessBoolean is useless but prints something");
    	}
    }
    Comme vous pouvez le voir, dans la "grosse" fonction, il y a deux actions distinctes à réaliser. L'une des deux est cependant un peu plus "profonde" que l'autre.

    Lors de la découpe en sous-fonctions, un choix doit être fait. Est-ce que je met les "niveaux" de profondeurs ensemble ( choix réalisé dans l'exemple), ou bien je détaille tout les niveaux de la "sous-fonction" directement déclarée au dessus avant de passer aux "sous-fonctions" suivantes ?

    Cette question peut paraitre triviale, mais quand j'ai en face de moi une fonction d'une 100aine de ligne pas spécialement compliquée, je préfère largement avoir a scroller quelques lignes plus haut/bas plutôt que de chercher ou est déclarée la 1ère sous-fonction, puis de chercher la seconde sous-fonction, et ainsi de suite jusqu'au dernier niveau de sous-fonction déclarée.

    De même, pour la compréhension du code, quand on découpe une fonction de 100 lignes en fonctions de 5 lignes, le temps de comprendre chaque fonctions de 5 lignes, de les remettre en perspective dans le code appelant, et faire ce travail jusqu'à la fonction initiale, il faut se demander si on a effectivement gagné du temps.

    Bref, oui, personne ne niera qu'une fonction de 5 lignes est plus facilement lisible qu'une fonction de 100 lignes. Personne ne niera non plus que cette façon de faire permet de repérer plus facilement le code redondant et aide à la factorisation. Maintenant, si on compare la structure complête d'une fonction de 100 lignes, avec son équivalent découpé (c'est à dire l'ensemble des fonctions de 4-5 lignes, et non plus une seule de ses fonction), la question de la simplicité de lecture du code n'est plus si triviale.

    My 2 cents.

    @Jeandido : La question n'est pas qu'une question de conception. Elle se pose aussi pour la maintenabilité du code. On peut concevoir une application, et la rendre difficile à maintenir, cela ne veut pas forcément dire qu'elle n'a pas bien été conçue.

  11. #31
    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 129
    Points
    28 129
    Par défaut
    Citation Envoyé par jeandido Voir le message
    La question discutée dans ce fil est plus une question de conception que de programmation.

    Ceux d'entre nous qui prennent le temps de pratiquer le minimum d'ingénierie logicielle en savent long.
    Desole de te contredire, mais la personne qui vient parler de regles de codage lors des phases de specification, elle n'a rien compris et devrait se faire remettre a sa place.

    Tu peux vouloir discuter pour chaque projet du nommage des fonctions, de l'indentation, des fonctions courtes ou longues, des librairies externes a utiliser ou non, etc... Ou bien tu le fais une fois pour tous les projets, et comme ca, lors des phases de specification, tu te concentres sur ton projet.

  12. #32
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Al_th Voir le message
    ...
    Bref, oui, personne ne niera qu'une fonction de 5 lignes est plus facilement lisible qu'une fonction de 100 lignes. Personne ne niera non plus que cette façon de faire permet de repérer plus facilement le code redondant et aide à la factorisation. Maintenant, si on compare la structure complête d'une fonction de 100 lignes, avec son équivalent découpé (c'est à dire l'ensemble des fonctions de 4-5 lignes, et non plus une seule de ses fonction), la question de la simplicité de lecture du code n'est plus si triviale.
    Je suis assez d'accord avec toi, et sur ce dernier point je dirais (pour ceux qui se souviennent ) que c'est comme la différence entre les imprimantes page-à-page et les imptimantes "informatiques" à l'ancienne..

    Aujourd'hui, tu imprimes un prog, et tu te retrouves avec des pages de 60 lignes.. Pas terrible pour avoir une vue d'ensemble.. Dans les imprimantes "continues", tu pouvais étaler tout le programme par terre ou au mur et avoir la vivusalisation de l'ensemble - ou de l'ensemble d'une partie/fonction - avec les niveaux de profondeurs de complexité, etc..

    Là aussi les informaticiens se sont tirés une balle dans le pied. En optant pour la "modernité" ils se sont auto-supprimé un excellent outil de travail..

    Et d'ailleurs, lorsque le projet est complexe, un diagramme du style autoCAD est vital, c'est à dire un diagramme détaillé que l'on peut visualiser avec differents zooms, mais qui permet de visionner justement l'arborescence / architecture de tout ou d'une partie du logiciel..

  13. #33
    Membre du Club
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2009
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Congo-Kinshasa

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2009
    Messages : 38
    Points : 65
    Points
    65
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Desole de te contredire, mais la personne qui vient parler de regles de codage lors des phases de specification, elle n'a rien compris et devrait se faire remettre a sa place.

    Tu peux vouloir discuter pour chaque projet du nommage des fonctions, de l'indentation, des fonctions courtes ou longues, des librairies externes a utiliser ou non, etc... Ou bien tu le fais une fois pour tous les projets, et comme ca, lors des phases de specification, tu te concentres sur ton projet.
    @gangsoleil : J'ai l'impression que tu n'as pas bien compris ce que tu as lu. Il n'est pas question de définir les règles de codage lors de la spécification. Je ne faisais que préciser la signification de "implémentation" et son rapport avec "la spécification" et "la conception". Tu veux bien relire le post encore une fois ?

  14. #34
    Expert confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 032
    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 032
    Points : 5 476
    Points
    5 476
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Je rebondis juste sur ce point, qui est a mon sens revelateur de la non-pertinence de l'etude : dans la plupart des IDE modernes, une commande unique (ctrl+clic par exemple) permet immediatement d'etre bascule vers le code de la fonction que l'on veut voir, puis une autre commande (clic sur une fleche, ctrl+backspace, ...) permet de revenir immediatement a l'appel ou on etait.
    Depuis on utilise des interfaces en veux tu en voilà, avec des factory, et 36 couches intermédiaires, sans parler de truc genre IOC. Du coup les IDE n'aident plus .


    @jeandido:
    La conception reste malgré tout à un niveau plus haut que le codage.
    Ca me rappel mon cours d'UML: à en croire le prof t'appuies sur générer une fois que tout tes diagrammes sont finis et pof voila ton application.

  15. #35
    Membre du Club
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2009
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Congo-Kinshasa

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2009
    Messages : 38
    Points : 65
    Points
    65
    Par défaut
    Citation Envoyé par Al_th Voir le message
    C'est un avis complêtement personnel, mais bien que je sois pour la découpe, je ne veux surtout pas être catégorique.

    En effet, comprendre une fonction/méthode de 4/5 lignes, c'est simple, cela demande très peu d'effort, et c'est rapide.

    Maintenant si je prends une fonction un peu compliqué, et que j'applique la rêgle "je découpe en fonctions de moins de 5 lignes", je suis absolument sur et certain que je comprendrais moins bien à la fin qu'au début.

    La raison en est très simple. Sur une fonction de 100 lignes, je n'ai pas toute les lignes sous les yeux. Sur mon poste de travail j'en aurais environ une 50aine, sur un laptop une 30aine, c'est pas assez on est d'accord. Maintenant, si je compare avec la même fonction découpée, avec la règle ci-desus, j'aurais à chaque fois tout le code d'une fonction sous les yeux. Mais je n'aurais jamais la structure complête de la fonction sous les yeux non plus. Chaque imbriquement de tests et ou de boucles sera une nouvelle "sous-fonction", et on s'y perd très facilement.

    Lors de la découpe en sous-fonctions, un choix doit être fait. Est-ce que je met les "niveaux" de profondeurs ensemble ( choix réalisé dans l'exemple), ou bien je détaille tout les niveaux de la "sous-fonction" directement déclarée au dessus avant de passer aux "sous-fonctions" suivantes ?

    Cette question peut paraitre triviale, mais quand j'ai en face de moi une fonction d'une 100aine de ligne pas spécialement compliquée, je préfère largement avoir a scroller quelques lignes plus haut/bas plutôt que de chercher ou est déclarée la 1ère sous-fonction, puis de chercher la seconde sous-fonction, et ainsi de suite jusqu'au dernier niveau de sous-fonction déclarée.

    De même, pour la compréhension du code, quand on découpe une fonction de 100 lignes en fonctions de 5 lignes, le temps de comprendre chaque fonctions de 5 lignes, de les remettre en perspective dans le code appelant, et faire ce travail jusqu'à la fonction initiale, il faut se demander si on a effectivement gagné du temps.

    Bref, oui, personne ne niera qu'une fonction de 5 lignes est plus facilement lisible qu'une fonction de 100 lignes. Personne ne niera non plus que cette façon de faire permet de repérer plus facilement le code redondant et aide à la factorisation. Maintenant, si on compare la structure complête d'une fonction de 100 lignes, avec son équivalent découpé (c'est à dire l'ensemble des fonctions de 4-5 lignes, et non plus une seule de ses fonction), la question de la simplicité de lecture du code n'est plus si triviale.

    My 2 cents.

    @Jeandido : La question n'est pas qu'une question de conception. Elle se pose aussi pour la maintenabilité du code. On peut concevoir une application, et la rendre difficile à maintenir, cela ne veut pas forcément dire qu'elle n'a pas bien été conçue.
    Je suis d'accord avec toi, tout comme avec tout le monde, sur le rapport entre quantité de code et facilité de compréhension. mewtow a posté quelques théories des (Boehm-Davis + al., 1992; El-Emam et al., 1999; El-Emam et al., 2001b) tentant d'expliquer la question d'un point de vue scientifique.
    Ce qui m'intrigue, cependant, c'est cette vision quantitative de l'organisation du code et cette tendance à vouloir découper le code source sur base de règles arithmétiques du genre : 1 fonction de 100 lignes est à diviser en 20 fonctions de 5 lignes. Une fonction n'est pas qu'un regroupement de N lignes, encore faut-il d'elle ait un sens en elle-même.
    J'admet que la conception reste à un niveau plus élévé que le codage, comme me l'a bien fait remarqué micka132. Mais, c'est justement là qu'il y a avantage à refléchir sur l'organisation du code de son application, puisqu'on est à un niveau d'abstraction un peu plus élévé. Par exemple, la technique consistant à organiser les méthodes de ses classes par attribution des responsabilités et définition des modalités d'interactions entre ces classes fait ses preuves. Il s'agit, là, d'un découpage logique, d'une organisation qualitative.

    Concernant la maintenabilité, je ne comprend très bien quand tu dis qu'on peut bien concevoir une application et la rendre difficile à maintenir. Une bonne conception conduit à un code lisible, compréhensible et maintenable.

  16. #36
    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 129
    Points
    28 129
    Par défaut
    Citation Envoyé par jeandido Voir le message
    Une bonne conception conduit à un code lisible, compréhensible et maintenable.
    Je ne suis pas d'accord. Cela peut aider, mais ce n'est pas forcement lié.

    La lisibilite du code, c'est autant une conception correcte (et donc un decoupage correct des fonctions) qu'une ecriture correcte du code.

    Et tu peux faire ce que tu veux en conception, si le developpeur ecrit du code pourrit, le code sera illisible, incomprehensible et non-maintenable.

  17. #37
    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 : 43
    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 362
    Points
    1 362
    Par défaut
    Ce qui m'étonne, c'est que la question du langage n'ait pas encore été évoquée. Pourtant, il y a des choses à dire.

    1) certains langages induisent des fonctions courtes, d'autres des fonctions longues
    Loin de moi toute idée de spoil, mais quand je compare la lisibilité du python et celle du C++, pour quelque chose comme une boucle sur une map, je doute. Coté python, c'est une ligne (un for), en C++ c'est deux itérateurs et un while avec du it++; Du coup, je me dis qu'en C++, les fonctions longues sont naturelles dans le langage. En C, pareil. En python, c'est déjà plus synthétique.

    2) le C# avec la notion de région, de snippnets, permet d'avoir un code super lisible

    Les autres n'ont pas ces notions. Ca facilite la vie, mais ça montre aussi que le code vit, que c'est un texte (presque) comme les autres. J'attends qu'un IDE permette de surligner du code, de le mettre en forme, pour que la lecture soit plus facile.

  18. #38
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 084
    Points
    7 084
    Par défaut
    Citation Envoyé par jeandido Voir le message
    Concernant la maintenabilité, je ne comprend très bien quand tu dis qu'on peut bien concevoir une application et la rendre difficile à maintenir. Une bonne conception conduit à un code lisible, compréhensible et maintenable.
    Je suis pas d'accord non plus, c'est comme si tu disais qu'un roman était bien écrit juste parce que le découpage en chapitre est juste.

    L'écriture et l'organisation du code est l'affaire du codeur pas du concepteur. Par ailleurs je connais de très bon concepteurs mais qui pondent du code crade et pleins d'erreur. Dans la même idée, un bon architecte n'est pas non plus un bon maçon, plombier ou électricien.

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

    Informations forums :
    Inscription : Décembre 2007
    Messages : 6 805
    Points : 32 095
    Points
    32 095
    Par défaut
    Citation Envoyé par jeandido Voir le message
    (.../...)
    Concernant la maintenabilité, je ne comprend très bien quand tu dis qu'on peut bien concevoir une application et la rendre difficile à maintenir. Une bonne conception conduit à un code lisible, compréhensible et maintenable.


    Enseignant chercheur est ton titre. Désolé, mais par rapport à des vieux briscards qui se sont tapés des codes de tout poil, tu n'est pas très bien plaçé pour comprendre la réalité du terrain. Ca peut paraitre condescendant, mais j'ai refondu complètement(en iso-fonctionnel, on changeait juste le format de sortie) un code massif de 36 ans d'âge. Avec, sur la seule année 2008, plus de 30 maintenances de la part de plus de 10 intervenants, certaines massives, rien que pour le programme principal(nous en avions 10 gros).

    C'est ça, la réalité de la vie d'une appli. "Je conçois, j'implémente en suivant pas à pas la conception", c'est une vision de l'esprit. ça n'existe pas.

  20. #40
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    91
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Novembre 2009
    Messages : 91
    Points : 133
    Points
    133
    Par défaut
    Ce qui m'intrigue, cependant, c'est cette vision quantitative de l'organisation du code et cette tendance à vouloir découper le code source sur base de règles arithmétiques du genre : 1 fonction de 100 lignes est à diviser en 20 fonctions de 5 lignes. Une fonction n'est pas qu'un regroupement de N lignes, encore faut-il d'elle ait un sens en elle-même.
    Bien entendu, cela va de soi.

    Une bonne conception conduit à un code lisible, compréhensible et maintenable.
    Il suffit que le travail soit découpé et réparti à des développeurs différents des concepteurs pour se rendre que ce n'est pas le cas du tout.

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