summaryrefslogtreecommitdiff
path: root/Rduire_les_temps_de_dveloppement_sans_sacrifier_la_qualit.txt
diff options
context:
space:
mode:
authorneodarz <neodarz@neodarz.net>2017-03-10 11:58:22 +0100
committerneodarz <neodarz@neodarz.net>2017-03-10 11:58:22 +0100
commitbc1d70343807104ccf64b6bde9b2db54270203ff (patch)
tree122467d5cad8688bc609a1509e922dce5d70d391 /Rduire_les_temps_de_dveloppement_sans_sacrifier_la_qualit.txt
downloadread_it_later-master.tar.xz
read_it_later-master.zip
Initiale releaseHEADmaster
Diffstat (limited to 'Rduire_les_temps_de_dveloppement_sans_sacrifier_la_qualit.txt')
-rw-r--r--Rduire_les_temps_de_dveloppement_sans_sacrifier_la_qualit.txt491
1 files changed, 491 insertions, 0 deletions
diff --git a/Rduire_les_temps_de_dveloppement_sans_sacrifier_la_qualit.txt b/Rduire_les_temps_de_dveloppement_sans_sacrifier_la_qualit.txt
new file mode 100644
index 0000000..7936251
--- /dev/null
+++ b/Rduire_les_temps_de_dveloppement_sans_sacrifier_la_qualit.txt
@@ -0,0 +1,491 @@
+Titre: Réduire les temps de développement sans sacrifier la qualité
+Auteur: LeBouquetin
+Date: Tue 21 Feb 2017 15:26:31 +0100
+Lien: https://linuxfr.org/users/lebouquetin/journaux/reduire-les-temps-de-developpement-sans-sacrifier-la-qualite
+
+Sommaire
+
+ * Avant-propos[1]
+ * Introduction[2]
+ * Comment réduire les temps de développement ?[3]
+ * Réduction de temps de développement avec perte de qualité[4]
+ * Réduction de temps de développement sans perte de qualité[5]
+
+ * Quel intérêt ?[6]
+ * Quelques techniques[7]
+
+ * Technique n°1 — ne pas prendre de décision à la place du client[8]
+ * Technique n°2 — se limiter strictement au cahier des charges[9]
+ * Technique n°3 — réduire le périmètre fonctionnel[10]
+ * Technique n°4 — faire du « test-driven » sur les interfaces[11]
+ * Technique n°5 — Faire de la conception progressive sur les composants
+ internes[12]
+ * Technique n°6 — Diviser pour mieux régner[13]
+ * Technique n°7 — Écrire du code simple[14]
+ * Technique n°8 — Écrire un script de setup d'un environnement fonctionnel[15]
+
+
+ * Conclusion[16]
+
+Avant-propos
+
+Ce journal parle de développement logiciel, de coûts, de qualité. Il est
+question de méthode et méthodologie plutôt que de technologies.
+
+Ce journal est un peu long… vous êtes averti(e)s ;)
+
+Introduction
+
+Je dirige une entreprise dont l'activité principale (en terme de chiffre
+d'affaire) est de faire de la prestation de services : développements
+techniques, développements d'applications distribuées et applications web sur
+mesure.
+
+Régulièrement les prospects et clients trouvent que les coûts sont élevés et
+cherchent à les réduire. C'est naturel.
+
+Le métier de la prestation de service est de vendre des jours/homme. Lorsqu'on
+veut réduire les coûts, le premier réflexe est donc de réduire le nombre de
+jours/homme.
+
+La problématique que j'essaie d'adresser ici est donc d'être capable de
+répondre à ces attentes, et si possible sans que ce soit au détriment de la
+qualité.
+
+client : dans cet article, le client est soit un client de l'entreprise soit un
+client interne — responsable produit, équipe marketing, utilisateur de l'outil
+interne, etc.
+
+anglicismes : par avance, merci de ne pas me tenir rigueur des anglicismes
+présents dans ce journal. Le quotidien du développeur est fait d'anglicismes —
+pour le meilleur et pour le pire.
+
+Comment réduire les temps de développement ?
+
+La manière la plus simple de réduire les temps de développement est d'adopter
+une stratégie de développement "agressive". Cette stratégie "agressive"
+signifie avec perte de qualité.
+
+Analogie : on pourrait faire un parallèle avec la compression d'images. Selon
+les algorithmes, la compression sera avec ou sans perte d'information. De la
+même manière, on pourra réduire les temps de développement avec ou sans perte
+de qualité — mais avec des niveaux de "compression" différents.
+
+Réduction de temps de développement avec perte de qualité
+
+A algoo, nous proposons 3 stratégies de développement qui essaient d'adresser
+différentes attentes en terme de temps de développement (mais également de
+qualité) :
+
+ 1.le développement de "prototype". On développe un démonstrateur, qui sera
+ jetable. Ca permet de valider un concept, faire des démos rapidement, mais
+ sans pérennité du code. Le coût en temps est réduit au maximum
+ puisqu'aucune réflexion sur la pérennité n'est menée.
+ 2.le développement de mvp[17]" — produit minimum viable. C'est un concept très
+ prisé par les startups ; pour simplifier il s'agit d'implémenter le minimum
+ de fonctionnalités dans un produit pour le rendre commercialisable. Dans ce
+ type de développement, les principales problématiques de pérennité seront
+ prises en compte, mais pas les autres. On aura alors un logiciel
+ "moyennement évolutif".
+ 3.le développement en mode "ingénierie logicielle". C'est la stratégie de
+ développement long-terme : on fait de l'architecture, de la conception, des
+ tests et de l'intégration continue — tests unitaires, test d'intégration,
+ tests fonctionnels, etc. C'est la stratégie que l'on favorise lorsqu'on
+ intervient sur un logiciel dont la durée de vie ciblée est de plusieurs
+ années.
+
+Les stratégies 1 et 2 sont moins couteuses que la 3, mais la qualité est
+partiellement sacrifiée et le niveau de finition également en faveur d'un temps
+de développement réduit (à court terme)
+
+Réduction de temps de développement sans perte de qualité
+
+Je vais vous présenter ici les techniques que nous mettons en oeuvre pour
+réduire les coûts de développement sans pour autant réduire la qualité (voire
+au contraire).
+
+Quel intérêt ?
+
+Réduire les coûts sans sacrifier la qualité est évidemment intéressant pour
+l'entreprise ou le client car :
+- soit vous avez la même chose pour un coût inférieur,
+- soit vous avez un périmètre fonctionnel plus étendu pour le même prix.
+
+Du côté des développeurs, en revanche, on a parfois l'impression qu'on essaie
+de brader les compétences.
+
+En réalité il ne s'agit pas de brader des compétences mais :
+
+ * d'industrialiser ce qui peut l'être sans surcoût,
+ * d'optimiser l'exploitation des compétences de chacun, des développeurs,
+ certes, mais aussi des autres intervenants, et en particulier des clients.
+
+Quelques techniques
+
+Les différentes techniques présentées ci-dessous ne sont pas exhaustives et ne
+demandent qu'à être complétées via vos commentaires. Elles ne sont pas non plus
+systématiques car chacune s'appliquera plus ou moins bien selon le projet,
+l'état d'avancement, les interlocuteurs — client interne, externe, client
+compétent techniquement, béotien, etc.
+
+Technique n°1 — ne pas prendre de décision à la place du client
+
+Objectif : éviter à tout prix de redévelopper une fonctionnalité non conforme
+aux attentes
+
+Quand on développe un logiciel, on le fait toujours pour un client. Ce client
+peut être externe — c'est le cas classique d'un prestataire de service, interne
+- on développe un logiciel à partir des demandes du marketing ou du responsable
+produit, ou encore "perso" (on développe un outil dont on a soi-même besoin).
+
+Les cahiers des charges et spécifications ne sont jamais complets. Il y a alors
+systématiquement des sujets à trancher.
+
+Les développeurs ont besoin de réponses pour avancer, mais ils n'ont pas la
+connaissance pour décider. Je parle bien de connaissance, pas de compétence :
+seul le client sait ce qu'il veut, et si le développeur sait ce dont le client
+a réellement besoin (cas typique : un client qui ne connait rien au métier du
+logiciel), il n'est toutefois pas en mesure de trancher seul.
+
+Pourquoi ? Parce que la solution "idéale" qu'il aura implémentée ne sera pas
+celle que le client veut donc probablement que le client ne sera pas satisfait
+(ce qui n'est pas bon), ou alors dans le pire des cas il va vouloir que le
+boulot soit refait, ce qui implique "re-développement", et dans tous les cas
+négociations, qui peuvent être coûteuses en temps (donc couteuses tout court,
+et pas la partie la plus agréable).
+
+Exemple : un cahier des charges qui indiquerait "l'utilisateur doit pouvoir
+être notifié".
+
+ * Est-ce qu'on veut des notifications par email ? des notifications sur sa
+ webapp ? par SMS ? Toutes ?
+ * Est-ce que l'utilisateur choisi lui-même quand et comment il est notifié ?
+
+Pour caricaturer, dans ce cas de figure, un développeur va avoir 2 réflexes :
+- soit il va aller droit au but - avec un système de notifications tel qu'il
+l'imagine, lui,
+- soit il va concevoir et implémenter un système complètement flexible.
+
+Dans le premier cas, la solution ne sera pas évolutive, et s'il est parti sur
+de mauvaises bases, c'est potentiellement tout son travail qui sera à refaire,
+sans compter la frustration d'avoir "travaillé pour rien" ou "de ne pas être
+écouté".
+
+Dans le second cas, on aura une solution "over-engineered" — de la surqualité,
+qui a un coût.
+
+La solution : au moindre choix, il faut demander au client. Et idéalement au
+client final. On a vite fait de "savoir" lorsqu'on est chef de projet ou
+responsable produit, mais la réalité est la même : c'est le client qui sait.
+
+Technique n°2 — se limiter strictement au cahier des charges
+
+Objectif : développer uniquement ce qui est commandé.
+
+Lorsque le client a rédigé son cahier des charges, il a pris le temps de
+réfléchir à ce dont il avait besoin. Idéalement, il fournira en plus du cahier
+des charge, un cahier des charges prévisionnel pour les versions suivantes, ou
+une stratégie d'évolution envisagée. Cette stratégie va permettre d'opérer des
+choix techniques et architecturaux mais ne doit en aucun cas générer de coûts
+de développement supplémentaires.
+
+Parfois, en tant que développeur, on se dit "ah mais si je fais ça de telle
+manière, ça prend juste quelques jours de plus et ça permet d'avoir un système
+plus évolutif". Et en général plus complexe, donc plus fragile.
+
+ * D'une part si cette flexibilité n'est exprimée nulle part il ne faut pas la
+ prendre en compte — il sera temps de l'implémenter le jour où elle sera
+ vraiment demandée (si ce jour arrive),
+ * d'autre part en règle général, plus un système est flexible, plus il est
+ complexe, plus il est fragile. Donc plus il nécessite de tests pour être
+ certifié "conforme".
+
+Si une certaine flexibilité est obtenue avec quelques jours de plus, il sera
+probablement préférable soit de ne rien faire, soit de prendre ces quelques
+jours pour blinder la couverture de tests automatiques. Ainsi, le code reste
+simple et robuste, et la future évolution sera plus facile à implémenter car
+toute régression sera décelée via les tests automatiques.
+
+Technique n°3 — réduire le périmètre fonctionnel
+
+Objectif : développer uniquement ce qui est nécessaire.
+
+Lorsqu'un client écrit un cahier des charges, il ne prend pas toujours le temps
+de prendre le recul nécessaire pour évaluer la pertinence de ses attentes.
+Concrètement, il va indiquer dans son cahier des charges l'ensemble des
+fonctionnalités qu'il attend, mais lorsqu'on présente un chiffrage mettant en
+relief le temps de développement associé à chaque fonctionnalité, il n'est pas
+rare que l'urgence de certains points devienne toute relative.
+
+Technique n°4 — faire du « test-driven » sur les interfaces
+
+Objectif : (dé)terminer les spécifications de manière exhaustive.
+
+Nous développons des applications web et des applications distribuées. Cela
+signifie en particulier la définition d'APIs (REST pour la majorité, mais pas
+nécessairement).
+
+*Note : API signifie Application Programming Interface, il s'agit des
+interfaces qui vont permettre de piloter votre logiciel.
+*
+
+Ces interfaces sont potentiellement très différentes du code qui est dessous,
+mais une chose est sûre : lorsqu'on entame le développement, on ne sait pas
+exactement ce qu'on doit faire.
+
+Dans le meilleur des cas, une partie du travail consiste à "finir les
+spécifications"
+(par exemple la gestion des cas d'erreur), dans le pire des cas, la tâche de
+développement consiste aussi à écrire les spécifications.
+
+La meilleure manière de faire ce travail de spécification — en tout cas de le
+terminer, est d'écrire les cas de test. Cela permet de se concentrer sur
+l'utilisation (donc le besoin) et non sur l'implémentation (la manière de faire
+les choses).
+
+Concrètement l'idée est d'écrire tous les cas de test puis de les exécuter à
+chaque nouvelle itération du développement. D'un taux initial de 100% d'erreur,
+on va finir par arrriver à 100% OK une fois que le développement est terminé.
+
+Ca n'aura pas coûté plus cher et le gain sera double :
+
+ * une conception adaptée au besoin,
+ * un refactoring simplifié car spécification complète (via les cas de test)
+ et 100% testée
+
+Dans l'hypothèse où l'on aurait commencé par le développement, puis écrit les
+tests, outre le fait qu'on prend le taureau par les cornes (on écrit la
+solution avant d'avoir écrit les spécifications), le risque est d'avoir conçu
+une solution qui ne va pas répondre à 100% des besoins, ce qui veut dire qu'on
+doit faire du refactoring ou qu'on accepte une couverture partielle des
+besoins.
+
+Faire du "test driven" sur les interfaces est une bonne chose, mais sur le
+reste ? Pas forcément.
+
+Les meilleures spécifications qu'on pourra obtenir/définir seront toujours sur
+les interfaces. Dans ce contexte écrire les tests revient simplement à
+transcrire les spécifications en code.
+
+Lorsqu'on travaille sur le développement (et la conception) interne(s), on a
+rarement des spécifications, on va plus (+) avancer à tâtons, ce qui correspond
+à la technique suivante.
+
+Technique n°5 — Faire de la conception progressive sur les composants internes
+
+Objectif : avoir quelque chose de fonctionnel le plus rapidement possible.
+
+Lorsqu'on conçoit un nouveau module logiciel, on sait rarement à l'avance
+exactement comment il doit être conçu et comment il va se comporter.
+
+En général, on découvre la réelle complexité progressivement parce qu'on pense
+au fur et à mesure à l'ensemble des cas de figure. Ce qui semblait initialement
+simple devient (très) compliqué ; du coup la question de « refactoriser » le
+code devient récurrent, etc, etc.
+
+L'idée ici est donc d'avoir au plus vite quelque chose qui fonctionne, et
+seulement ensuite de se poser la question de comment concevoir le module pour
+découper la complexité.
+
+On assimile le métier via une première version "brouillon" puis on modélise ce
+métier proprement.
+
+Cela signifie en gros :
+
+ 1.développer le composant fonctionnant dans le cas nominal en mode "proto"
+ 2.au cours du 1. on identifie naturellement les cas d'erreur possibles / à
+ traiter (et on les documente d'une manière ou d'une autre dans le code)
+ 3.on a un code fonctionnel, il est alors temps :
+
+ 1.de rationaliser la conception,
+ 2.de gérer/traiter les cas d'erreur,
+ 3.d'écrire les tests unitaires une fois les composants clairement découpés.
+
+
+On sépare les tâches d'assimilation métier et de modélisation logicielle.
+
+Et pour la modélisation logicielle, rien de tel que la technique suivante.
+
+Technique n°6 — Diviser pour mieux régner
+
+Objectif : simplifier la maintenance et l'évolutivité du code.
+
+Les développeurs n'aiment que rarement faire de la maintenance sur du code.
+Personnellement, je trouve que c'est la partie la plus passionnante du travail
+car les contraintes sont fortes.
+
+Bien souvent les jeunes diplômés (en particulier) ne veulent pas faire de
+maintenance mais veulent concevoir un logiciel entier. Et lorsqu'il s'agit de
+reprendre du code, plutôt que le faire évoluer ils préfèrent souvent tout
+refaire de zéro.
+
+Pourtant le code a une intelligence propre : il répond à des besoins métiers
+qui ont été accumulés en son sein, et lorsqu'on ré-écrit un logiciel
+complètement, c'est une grande partie de cette connaissance que l'on perd.
+
+La raison pour laquelle la maintenance n'est pas sexy est que très souvent le
+code est un véritable nœud de fonctionnalités et responsabilités, et lorsqu'on
+aperçoit un bout et que l'on essaie de tirer sur la ficelle, c'est toute la
+pelote qui vient. Et plus on tire, plus les nœuds se resserrent ;)
+
+Hors, ré-écrire un code complet est très coûteux, et carrément exorbitant si on
+considère qu'on veut réécrire à périmètre fonctionnel constant. (attention :
+toutes les ré-écritures n'ont pas pour objectif d'être iso-fonctionelles)
+
+La bonne solution pour faciliter la maintenance est de découper le code pour
+qu'il soit plus facile de le faire évoluer.
+
+le principe est simple : "un module = une responsabilité". Et inversement.
+
+Prenons un exemple concret : je veux faire un logiciel de gestion de tâches
+(todo). J'identifie spontanément 3 responsabilités :
+
+ 1.le stockage des informations
+ 2.l'intelligence du logiciel - le noyau
+ 3.l'interface "utilisateur" (ça peut être une API REST)
+
+Du MVC ? Si on veut, mais c'est le niveau 1. du découpage.
+
+Imaginons, qu'on ait développé le dit logiciel en 3 modules : une interface
+utilisateur en QT, un module "kernel" qui implémente l'intelligence et un
+module "database" qui stocke dans une base SQLite.
+
+Un jour, mon client me demande s'il est possible de faire une interface web et
+qu'il aimerait pouvoir stocker dans une base de données MySQL, voire MongoDB.
+
+Il y a du travail, mais on va pouvoir découper ça relativement facilement. Par
+rapport au cas précédent, les 3 modules se décomposent désormais 7 modules (7
+responsabilités) :
+
+ 1.l'instanciation du "driver de données" (une fabrique)
+ 2.le driver SQLite (qui va reprendre grosso modo le code de l'ancien composant
+ "stockage des informations")
+ 3.le driver MongoDB (qui va implémenter une interface compatible avec l'ancien
+ composant "stockage des informations")
+ 4.le noyau du logiciel (qui va désormais manipuler des objets génériques)
+ 5.l'interface utilisateur QT
+ 6.Un composant "web" qui implémente une API REST/Json
+ 7.Un composant "web" frontend qui se connecte sur l'API.
+
+Les composants 1, 2 et 3 de l'ancien logiciel sont quasiment naturellement les
+2, 4 et 5 du nouveau.
+
+Dans cette décomposition, chaque composant a une unique responsabilité. Et
+chaque responsabilité est gérée par un composant unique.
+
+Note : les parties en gras qui signifient "et inversement" mettent en relief
+qu'une responsabilité qui serait découpée entre plusieurs composants rend la
+maintenance et l'évolutivité aussi difficile que des composants aux
+responsabilités multiples.
+
+L'illustration caricaturale dans mon domaine est Django, qui n'incite en aucun
+cas à faire ce type de découpage :
+
+ * Les vues Django implémentent de l'intelligence "métier" (et donc si on veut
+ ré-implémenter les même fonctionnalités via une autre interface, c'est un
+ gros travail de refactoring),
+ * La validation des données va être implémentée dans des formulaires ou dans
+ les modèles eux-même voire dans des "ModelView",
+ * Lorsqu'on travaille avec Django Rest Framework (la seule vraie raison
+ d'utiliser Django en 2017), les serializers risquent d'implémenter toute la
+ logique — et de fait devenir le "kernel" partiel d'une application.
+
+Bien entendu on peut exploiter Django différemment, mais la pratique que l'on
+constate est celle-ci.
+
+Technique n°7 — Écrire du code simple
+
+Objectif : simplifier la maintenance et l'évolutivité du code.
+
+« Ce qui se conçoit bien s'énonce clairement » — Nicolas Boileay-Despréaux.
+
+Souvent les développeurs veulent faire des choses compliquées, et exploiter les
+fonctionnalités d'un langage au maximum. Mais la réalité c'est qu'un logiciel
+qui est écrit simplement fonctionne aussi bien qu'un logiciel exploitant toutes
+les particularités d'un langage.
+
+Il fonctionne aussi bien, et ça ne coûte pas plus cher à écrire.
+Et il coûte beaucoup moins cher à lire, donc à comprendre, donc à maintenir et
+faire évoluer.
+
+Parfois les arguments sont d'écrire du code concis ou du code "esthétique",
+mais la concision trop extrême devient inaccessible.
+
+Analogie : prenons un four qui propose 2 boutons rotatifs - un pour régler la
+position et un pour régler la température. Ce four est beaucoup plus simple à
+appréhender qu'un four avec un unique bouton rotatif sur lequel on peut
+"cliquer" pour entrer dans des menus. Esthétiquement certains diront que c'est
+plus joli - c'est subjectif. Par contre ce qui n'est pas subjectif, c'est que
+c'est moins naturel à utiliser et moins ergonomique. Pour le confirmer, il
+suffit de regarder ce qui se fait dans les cuisines des restaurants : on
+industrialise la cuisine, et les choix qui sont opérés sont représentatif : du
+gaz, des boutons ronds, un bouton par fonctionnalité.
+
+Quand vous codez, imaginez que vous êtes un chef étoilé :)
+
+Technique n°8 — Écrire un script de setup d'un environnement fonctionnel
+
+Objectif : monter un environnement de test en 1 minute
+
+Dans l'esprit du Joel Test[18], il est de bon ton d'écrire un script de setup
+qui permet d'obtenir un environnement fonctionnel en une commande voire deux.
+Cela permet de très rapidement intégrer un nouveau développeur (ou un nouveau
+poste de développement), cela permet aussi très rapidement de mettre au point
+un nouvel environnement de test, totalement vierge.
+
+Cela réduit le frein au test, et augmente donc le nombre de tests et donc le
+nombre de bugs détectés (et probablement aussi le nombre de bugs résolus).
+
+Plus on peut tester, plus on trouve de bugs, moins la qualité diminue. Écrire
+un tel script prendra probablement quelques heures en début de projet, mais ces
+heures "perdues" seront largement compensées par les heures perdues à mettre en
+place des environnements, à tester ou ne pas tester car le setup est trop
+pénible.
+
+Inutile d'en dire plus.
+
+Conclusion
+
+Selon les cas et les projets, nous n'appliquons pas nécessairement toutes ces
+techniques.
+
+Un point à prendre également en compte et qui n'apparait pas ici : derrière
+l'idée de réduire les temps de développement se cachent différents aspects. On
+y trouvera naturellement des notions de coûts — moins de jours de développement
+coûtent moins cher (c'est le cas initial à l'origine de ce journal), mais on y
+trouve aussi des notions de time-to-market. Moins de temps de développement,
+c'est une arrivée sur le marché plus rapide. Ce qui génère potentiellement des
+gains différents.
+
+Le time-to-market… c'est notamment la raison pour laquelle pas mal de startup
+fabriquent une première version en mode "mvp" voire carrément en mode "proto" :
+cela permet de prendre les parts de marché initiales, quitte à complètement
+redévelopper le produit par la suite — une fois que le marché a été pris, la
+concurrence devient difficile, la startup est devenue rentable et les dépenses
+de R&D nécessaires à la construction d'un système propre et robuste deviennent
+envisageables.
+Télécharger ce contenu au format Epub[19]
+
+Lire les commentaires[20]
+
+Liens:
+[1]: http://linuxfr.org/journaux.atom#avant-propos (lien)
+[2]: http://linuxfr.org/journaux.atom#introduction (lien)
+[3]: http://linuxfr.org/journaux.atom#comment-r%C3%A9duire-les-temps-de-d%C3%A9veloppement (lien)
+[4]: http://linuxfr.org/journaux.atom#r%C3%A9duction-de-temps-de-d%C3%A9veloppement-avec-perte-de-qualit%C3%A9 (lien)
+[5]: http://linuxfr.org/journaux.atom#r%C3%A9duction-de-temps-de-d%C3%A9veloppement-sans-perte-de-qualit%C3%A9 (lien)
+[6]: http://linuxfr.org/journaux.atom#quel-int%C3%A9r%C3%AAt (lien)
+[7]: http://linuxfr.org/journaux.atom#quelques-techniques (lien)
+[8]: http://linuxfr.org/journaux.atom#technique-n1--ne-pas-prendre-de-d%C3%A9cision-%C3%A0-la-place-du-client (lien)
+[9]: http://linuxfr.org/journaux.atom#technique-n2--se-limiter-strictement-au-cahier-des-charges (lien)
+[10]: http://linuxfr.org/journaux.atom#technique-n3--r%C3%A9duire-le-p%C3%A9rim%C3%A8tre-fonctionnel (lien)
+[11]: http://linuxfr.org/journaux.atom#technique-n4--faire-du-test-driven-sur-les-interfaces (lien)
+[12]: http://linuxfr.org/journaux.atom#technique-n5--faire-de-la-conception-progressive-sur-les-composants-internes (lien)
+[13]: http://linuxfr.org/journaux.atom#technique-n6--diviser-pour-mieux-r%C3%A9gner (lien)
+[14]: http://linuxfr.org/journaux.atom#technique-n7--%C3%89crire-du-code-simple (lien)
+[15]: http://linuxfr.org/journaux.atom#technique-n8--%C3%89crire-un-script-de-setup-dun-environnement-fonctionnel (lien)
+[16]: http://linuxfr.org/journaux.atom#conclusion (lien)
+[17]: https://fr.wikipedia.org/wiki/Produit_minimum_viable (lien)
+[18]: https://www.joelonsoftware.com/2000/08/09/the-joel-test-12-steps-to-better-code/ (lien)
+[19]: https://linuxfr.org/users/lebouquetin/journaux/reduire-les-temps-de-developpement-sans-sacrifier-la-qualite.epub (lien)
+[20]: https://linuxfr.org/users/lebouquetin/journaux/reduire-les-temps-de-developpement-sans-sacrifier-la-qualite#comments (lien)