Journal Petite^W Longue critique du livre Code Complete

Posté par (page perso) .
25
4
août
2011

Sommaire

J'aime bien suivre l'actualité générale autour du Libre (comprendre : lire DLFP), suivre quelques blogs, etc. Mais j'aime bien aussi lire des livres traitant d'informatique. Et le dernier en date, c'est justement Code Complete, de Steve McConnell (2e édition).

[/!\ § d'accroche]
En bref : si vous aimez la programmation, il y a des chances que vous aimerez encore plus ce « métier » situé entre l'art et l'ingénierie après avoir lu ce livre. En tout cas c'est mon sentiment.

Un petit problème…

Alors, pour ceux qui ont déjà cliqué sur le premier lien, oui, l'éditeur est Microsoft Press. Ne pas acheter ce livre juste à cause de ça est idiot ÀMHA. Comme je suis un libriste comme tout le monde ici, mon avis sur le sujet vous semblera peut-être intéressant :

  • Déjà, les exemples de code, qui sont assez nombreux, sont soit en C++ (bien), Java (moins bien) ou Visual Basic (argh !). Mais dans ce genre de livre, le langage n'a pas trop d'importance. Et le Visual Basic n'a pas une syntaxe trop exotique, pas comme le Smalltalk par exemple qui est parfois utilisé dans le livre Design Patterns.

  • Le lien avec Microsoft ou Windows se limite juste à quelques références ou anecdotes. De ce point de vue là, c'est très varié.

  • Le monde OpenSource, de UNIX et de GNU/Linux n'est pas oublié, mais on peut regretter une absence totale du Libre (eh non, OpenSource ≠ Libre).

OK. Mais de quoi traite ce livre au juste ?

Construire un programme qui fonctionne, ce n'est pas difficile. En construire un dont le code est simple à comprendre, qui est facilement maintenable, et où on n'a pas perdu du temps à travailler sur des choses inutiles ou peu significatives, c'est une autre paire de manches. Code Complete explique donc plein de bonnes pratiques pour arriver à cet objectif.

Dans un projet de programmation, écrire le code source est inévitable. Donc autant le faire le mieux possible. Mais en-dehors de l'écriture du code, il peut y avoir beaucoup d'autres choses (surtout dans les entreprises, moins pour un projet personnel) :

  • définir le problème à résoudre ;
  • définir le cahier des charges, les exigences ;
  • réfléchir à l'architecture du logiciel ;
  • {écrire le code} ;
  • tester et déboguer ;
  • intégration des différents composants ;
  • refactoring (améliorer du code existant) ;
  • améliorer les performances, mais pas n'importe comment.

Tout ceci ne se fait évidemment pas séquentiellement, mais de manière itérative. Ainsi, si on fait une erreur dans une des premières étapes, on s'en rend plus vite compte, et l'impact est moins important.

Code Complete parle de tous ces sujets, mais les trois premiers points de manière résumée/introductive. Et pour les autres sujets autres que {écrire le code} (qui est la partie la plus développée du livre), il y a pas mal d'explications, mais en fin de chapitres il y a à chaque fois des références vers d'autres bouquins plus complets.

Quelques exemples de bonnes pratiques

Vous vous demandez surement comment on peut écrire un ouvrage de 900 pages, alors que le sujet principal est l'écriture de code. Quels genres de conseils y sont donnés ?

Pour donner un exemple très précis, prenons l'écriture du nom d'une fonction. Le nom d'une fonction, c'est très important, pour savoir ce qu'elle fait exactement, et pour la retrouver et la réutiliser facilement quand on en a besoin.

Si avant de commencer à écrire la fonction, on a du mal à lui donner un nom, c'est qu'il y a un problème : on n'a pas bien réfléchi à l'avance ce que la fonction est censée faire exactement, et dans ce cas-là, soit on lui donner un nom bateau genre « handle_stuff() », et la fonction fait plein de diverses choses. Soit on change d'avis, et au lieu d'écrire une fonction fourre-tout, on la décompose en plusieurs fonctions qui ne font qu'une chose, mais qui le font bien™. Tient, ça ressemble vachement à la philosophie UNIX !

Et là, les programmeurs chevronnés se disent : « pff, c'est tout à fait logique, je n'ai pas besoin de ce genre de conseils ». Sur ce point-là, je n'ai pas un avis très tranché. Il y a quelques parties du livre (mais pour ma part ça ne représentait pas beaucoup) qui s'adressent clairement aux débutants. D'ailleurs dans ce cas, il y a un avertissement au début du chapitre, pour dire que certains peuvent sauter une ou plusieurs sections. En tout cas, sur la quatrième de couverture, il est clairement marqué que c'est adressé tant aux débutants qu'aux programmeurs plus expérimentés.

En programmation, il y a beaucoup de choses qu'on fait par habitude. Si on prend des bonnes habitudes dès le début, tout va bien. Mais le problème c'est qu'on est pas toujours conscient qu'on a pris de mauvaises habitudes. Je vais prendre un exemple qui m'a assez choqué dans le livre, mais qui s'avère au final bénéfique.

Pratiquement tous les programmeurs, pour écrire des boucles, utilisent les noms de variables i, j, voir k (mais trop d'imbrications rend le code plus difficile à suivre, mais là n'est pas le sujet). Il est conseillé d'utiliser plutôt des noms plus long qui décrivent bien ce que l'index représente. Ainsi, quand on veut modifier la valeur d'un tableau imbriqué par exemple, au lieu de lire :

score[i][j] = ...;

on lit :

score[ teamIndex ][ eventIndex ] = ...;

En ayant des noms plus explicites, en rapport avec le domaine d'application, il y a moins de risque de confondre les deux variables, et on comprend mieux ce que le code fait.

Et pourtant, l'utilisation des i, j, etc. est très très courant. Pourquoi ? Si c'est pour écrire le code plus vite, ce n'est pas une bonne raison. On lit beaucoup plus de code qu'on en écrit. En règle générale, il faut écrire du code non pas pour la machine, mais pour soi-même et les autres personnes qui vont le lire.

Il y a comme ça certains conseils généraux qui sont souvent répétés. Certains préfèrent que certaines informations soient répétées pour mieux les retenir, d'autres trouvent ça inutile. Pour ces derniers, il y a peut-être d'autres livres sur le même sujet qui leurs conviendraient mieux.

Autres points généraux sur lequel l'auteur insiste

  • Un des buts premiers de la programmation est de gérer la complexité, en faisant abstraction de certaines choses, à tous les niveaux. L'exemple typique est la programmation orientée objet : pour utiliser une classe, il ne faut pas (normalement) savoir comment elle fonctionne en interne.

  • Programmer en termes du problème au lieu des détails techniques. Par exemple on s'en fiche de savoir quelle structure de données est utilisée pour stocker certaines informations. Donc on préfèrera des noms de fonctions tels que get_last_document() plutôt que get_top_stack().

  • Faire attention aux signes qui montrent que notre code est mal écrit : par exemple quelqu'un qui nous dit que notre code est difficile à comprendre. Ou bien des warnings lors de la compilation, etc.

  • Ne pas se focaliser sur une seule et unique méthode. Aucune méthode n'est parfaite pour tous les types de projets. Trouver les bonnes techniques se fait par une heuristique, il n'y a pas de procédé clairement défini. C'est comme un ouvrier avec une boite à outils. Il n'y a pas un outil qui convient pour tout.

Un bon point de départ

Le texte est rempli de références vers d'autres ouvrages, donnant souvent envie d'en apprendre plus. Le dernier chapitre est d'ailleurs consacré rien qu'à ça.

Peut-être qu'en lisant ce journal, vous avez pensé à The Art of Computer Programming de Donald Knuth. Cette série de livres détaille en profondeur l'algorithmique et les structures de données. Code Complete aborde évidemment aussi ce sujet, mais il en aborde tellement d'autres que ce n'est pas comparable.

Que dire de plus ?

Encore beaucoup de choses, mais je vais m'arrêter là pcq c'est déjà suffisamment long comme ça. Pour ceux qui ont lu jusqu'ici, merci :)

Ah non, j'ai menti, encore une chose. Je pense qu'il existe une traduction en français, mais comme toute traduction d'un livre informatique écrit à la base en anglais, il est plutôt conseillé de lire l'original. J'ai déjà vu des livres en français où le code source était mal formaté, des mots comme CPU sont traduits en UC (Unité Centrale), etc. Bref, à déconseiller.

  • # FR

    Posté par (page perso) . Évalué à 10.

    Je pense qu'il existe une traduction en français, mais comme toute traduction d'un livre informatique écrit à la base en anglais, il est plutôt conseillé de lire l'original. J'ai déjà vu des livres en français où le code source était mal formaté, des mots comme CPU sont traduits en UC (Unité Centrale), etc.

    Oui, elle existe : http://www.amazon.fr/Tout-sur-code-concevoir-logiciel/dp/2100487531
    Le livre est plutôt de bonne qualité, pas rencontré d'erreurs flagrantes de code mal formaté (ce serait un comble pour ce livre...) ni de terme, etc.

    Bref, à déconseiller.

    Ben non, désolé mais c'est vraiment n'importe quoi ce que tu écris sur ce point. Franchement hein.
    Tu déconseille de lire une version d'un livre

    • que tu n'as jamais lu
    • dont tu n'as aucune idée si la traduction est bonne ou non
    • uniquement en se basant sur des généralités à la con

    Alors non, au contraire, moi je le conseille, et je l'ai lu en français.
    Avant de déconseiller un livre, ait un vrai avis dessus ça serait mieux.

    C'est con parce que terminer là dessus ça ne donne pas du tout une bonne image.

    • [^] # Re: FR

      Posté par (page perso) . Évalué à 5.

      Ah ben tant mieux s'il est bien écrit, tu fais bien de le dire.

      Mais personnellement, en informatique je préfère lire de l'anglais. J'ai donné une raison (les termes techniques qui ne sonnent pas bien en français). Mais c'est aussi un bon entrainement, on apprend du vocabulaire, etc.

      Aussi, le dernier paragraphe c'était histoire de troller un peu vers la fin :) Il fallait bien que quelqu'un ne soit pas du même avis.

      « Un animal d'une atterrante stupidité : il est persuadé que si vous ne le voyez pas, il ne vous voit pas non plus » (H2G2)

    • [^] # Re: FR

      Posté par (page perso) . Évalué à 5.

      Dans le lien que tu donnes, il y a un commentaire contradictoire :

      [...]
      le vocabulaire est parfois incorrect et que vous vous énerverez régulièrement devant les coquilles.

      « Un animal d'une atterrante stupidité : il est persuadé que si vous ne le voyez pas, il ne vous voit pas non plus » (H2G2)

      • [^] # Re: FR

        Posté par (page perso) . Évalué à 4.

        Je ne me souviens pas m'être énervé contre des erreurs.
        C'est peut-être pas toujours le mot parfais, mais critiquer révision de code / revue de code ... hum... j'ai pas vraiment de problème à comprendre ce que veut dire "revoir un code".
        J'aurais été moins sympa si j'avais lu des conneries comme cadriciel par exemple.

        Dans tous les cas, anglais ou français, à conseiller et à lire.

  • # Les points négatifs

    Posté par (page perso) . Évalué à 4.

    Oups. J'ai oublié de parler des points négatifs.

    Dans le livre il y a dans les marges pas mal de références vers d'autres sections du livre, mais les références sont trop vagues (il faut chercher une sous-sous-section parmi une quinzaine de pages parfois…), il faudrait des numéros de pages.

    Et aussi, le texte est en « fer à gauche » au lieu d'être justifié. Mais bon on s'y fait.

    Sinon, hors-sujet, mais je dois pas être fait pour le marketing : je suis arrivé à écrire « Bref, à déconseiller. » tout à la fin, alors que je n'ai montré que des points positifs du livre :)

    « Un animal d'une atterrante stupidité : il est persuadé que si vous ne le voyez pas, il ne vous voit pas non plus » (H2G2)

  • # Noms longs ?

    Posté par . Évalué à 5.

    Concernant l'exemple que tu donnes de bonne pratique, je reste dubitatif. Je trouve que donner des noms longs a des variables iteratives alourdit le code a la lecture. Généralement, le nom de l'array est suffisamment clair pour qu'on sache de suite à quoi correspondent les index. Si ce n'est pas le cas, la solution n'est pas les noms longs, mais de repenser le nom de l'array.

    • [^] # Re: Noms longs ?

      Posté par (page perso) . Évalué à 4.

      Oui, c'est un des conseils qui est assez controversé.

      Ce qui gêne plus, c'est quand le i ou le j est utilisé en-dehors de la boucle, pour retenir par exemple le dernier index valide ou qqch du genre. Dans ce cas il vaut carrément mieux créer une autre variable retenant cet index, avec un nom qui permet de savoir de quoi il s'agit.

      « Un animal d'une atterrante stupidité : il est persuadé que si vous ne le voyez pas, il ne vous voit pas non plus » (H2G2)

    • [^] # Re: Noms longs ?

      Posté par (page perso) . Évalué à 3.

      Tout à fait d'accord. surtout qu'on connaît immédiatement à quoi correspondent i et j en regardant le contenu du "for" au dessus, donc on sait de quoi on parle.

      C'est aussi l'intérêt de i, j, k. En les utilisant correctement on sait immédiatement qu'une variable j est un indice de boucle, que cette boucle j est imbriquée une la boucle i, etc.

      • [^] # Re: Noms longs ?

        Posté par (page perso) . Évalué à 2.

        Voici ce qui est dit dans le livre, qui s'applique tant pour les for, que pour les while :

        Si un index de boucle doit être utilisé en-dehors de la boucle (parfois bien après), c'est préférable de lui donner un nom long.

        Si une boucle est assez longue, il est facile d'oublier à quoi correspond le i ou le j (donc il faut souvent revenir en haut de la boucle pour voir à quoi elle correspond). Du code est souvent modifié, étendu, et copié dans d'autres programmes, donc beaucoup de programmeurs expérimentés évitent complètement des noms comme i.

        Une des raisons pour lesquelles les boucles s'allongent est qu'elles sont imbriquées. Pour améliorer la lisibilité, il vaut mieux mettre des noms longs. Ça permet d'éviter de confondre i et j, et ça rend certaines lignes plus informatives (comme je l'ai expliqué dans le journal).

        Si vous devez vraiment utiliser i, j et k, faites le uniquement pour des boucles simples (donc qui ne sont pas imbriquées, et qui ne sont pas très longues, et dont l'index n'est pas utilisé en-dehors). Mais pour éviter tout problème, c'est plus simple de se donner une règle où on n'utilise pas du tout les i, j et k.


        Voilà, pour moi la meilleure raison est la première, que j'avais déjà expliqué dans le commentaire juste au-dessus.

        « Un animal d'une atterrante stupidité : il est persuadé que si vous ne le voyez pas, il ne vous voit pas non plus » (H2G2)

        • [^] # Re: Noms longs ?

          Posté par . Évalué à 3.

          Je rajouterais que quand les indices ne sont pas utilisés dans l'ordre (exemple : score[j][i]).

          Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

    • [^] # Re: Noms longs ?

      Posté par . Évalué à 8.

      Pour moi, les index de boucles montrent plutôt que le langage manque de structure de boucle permettant vraiment d'itérer sur des tableaux/listes pour faire autre chose que bêtement parcourir les valeurs. Moi j'ai envie de pouvoir modifier, revenir en arrière ou supprimer l'élément actuel ou en ajouter un autre avant ou après, de refaire un tour de boucle sur l'élément actuel, sur le précédent ou d'en sauter un.

      À chaque fois que je doit transformer une belle boucle foreach en un for ou while avec des variables de boucles qui ne représentent rien, je trouve ça dommage. C'est pas avec des conventions de codages stupides comme "i,j,k interdit" qu'on rend des variables de boucles jolies.

      Une bonne variable de boucle est une variable de boucle morte.

      • [^] # Re: Noms longs ?

        Posté par (page perso) . Évalué à 4.

        Oui, Python ou Ruby sont beaucoup plus pratique pour ça.

        Mais si tu dois faire du C, tu n'as pas le choix…

        « Un animal d'une atterrante stupidité : il est persuadé que si vous ne le voyez pas, il ne vous voit pas non plus » (H2G2)

        • [^] # Re: Noms longs ?

          Posté par . Évalué à 4.

          Mais si tu dois faire du C, tu n'as pas le choix…

          En fait si grâce à l'arithmétique des pointeurs :

          #include "stdio.h"
          
          #define TAILLE 10
          
          int main(char** argv) {
            int scores[TAILLE] = {1, 2, 6, 5, 2, 1, 9, 8, 1, 5};
          
            for(int* score = scores; score < scores + TAILLE; ++score) {
              printf("score = %d\n", *score);
            }
          
            return 0;
          }
          

          Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)

  • # Sur ma liste

    Posté par . Évalué à 3.

    Ta critique me fait rajouter ce livre sur ma liste de livre de programmation à lire.
    Mais d'abord il faut que je finisse The Pragmatic Progammer et Beautiful Code qui sont très bons aussi.
    Mention spéciale à Beautiful Code qui permet de voir des grands noms de la programmation s'extasier devant des lignes de code.

    • [^] # Re: Sur ma liste

      Posté par (page perso) . Évalué à 2.

      En ayant lu The Pragmatic Programmer, tu risques de connaitre déjà beaucoup de chose en lisant Code Complete. Mais Code Complete parle de plus de sujets.

      Beautiful Code est sorti en 2007, donc c'est normal que Code Complete (2e édition en 2004) ne le référence pas, mais ça a l'air intéressant. Il y a aussi Programmers at Work, qui est plus ancien.

      « Un animal d'une atterrante stupidité : il est persuadé que si vous ne le voyez pas, il ne vous voit pas non plus » (H2G2)

      • [^] # Re: Sur ma liste

        Posté par . Évalué à 2.

        Il faut savoir que Beautiful Code n'est pas axé sur les conseils ou la pédagogie. Ce sont plutôt des discussions autour de codes existants et qui ont la particularité d'être "beaux" aux yeux des auteurs.
        Après on peut en tirer des enseignements personnels.

  • # -

    Posté par (page perso) . Évalué à 5.

    En parlant de bouquins de programmation (enfin presque), certains ont-ils déjà lu certains de ces livres et pourraient donner leur avis dessus ?

    • Clean Code - A Handbook of Agile Software Craftmanship (Robert C. Martin)
    • Refactoring: Improving the Design of Existing Code (Martin Fowler)
    • [^] # Re: -

      Posté par (page perso) . Évalué à 3.

      Refactoring: Improving the Design of Existing Code (Martin Fowler)

      Je ne l'ai pas lu, mais à la fin du chapitre sur le refactoring dans Code Complete, c'est la seule ressource additionnelle qui est donnée, avec ce commentaire :

      This is the definitive guide to refactoring. It contains detailed discussions of many of the specific refactorings summarized in this chapter, as well as a handful of other refactorings not summarized here. Fowler provides numerous code samples to illustrate how each refactoring is performed step by step.

      Mais il faut savoir que la 2e édition de Code Complete est sortie en 2004, donc il se peut qu'un autre livre plus récent, et peut-être meilleur, est sorti.

      « Un animal d'une atterrante stupidité : il est persuadé que si vous ne le voyez pas, il ne vous voit pas non plus » (H2G2)

    • [^] # Coder proprement

      Posté par (page perso) . Évalué à 3.

      J'ai lu (enfin, pas fini, c'est en pause) la traduction française du premier, qui s'intitule « Coder proprement », et je le trouve vraiment très bien (et la traduction ne m'a pas choqué). Tous les exemples sont en Java (aaargh), et certains passages sont clairement java-centriques, mais ce n'est pas plus handicapant que ça.
      En bref : je le conseille vivement.

    • [^] # Code complete

      Posté par . Évalué à 2.

      Je connais bien Clean Code, c'est à mon avis un excellent bouquin. C'est très bien écrit, plein de bons conseils et est très rigoureux. Il revient très souvent sur les concepts les plus importants, avec beaucoup d'humour. Par exemple, l'auteur écrit: "Première règle: les fonctions doivent être courtes. Deuxième règle: être encore plus courte que ça!" et donne des exemples de bonne pratique. Le code est uniquement Java, par conséquent le programmeur C++ y retrouvera ses petits. Un excellent choix.

  • # Un autre: L'art du Code

    Posté par (page perso) . Évalué à 4.

    Un livre déjà ancien (1995), paru chez Microsoft Press aussi, de Steve Maguire.

    Où il décrit la mise en place de certaines règles de développement afin de limiter les bugs... et les utilisateurs qui ralent parce que la version debug d'une libraririe a ajouté des sorties en erreur sur les arguments invalide... et que leur logiciel ne fonctionne plus.

    Python 3 - Apprendre à programmer en Python avec PyZo et Jupyter Notebook → https://www.dunod.com/sciences-techniques/python-3

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.