<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
  <title>L'Agilitateur - En français</title>
  <link>http://agilitateur.azeau.com/</link>
  
  <description>Création de logiciels : de l'agilité à l'artisanat</description>
  <language>fr</language>
  <pubDate>Thu, 23 May 2013 10:23:21 +0200</pubDate>
  <copyright />
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Agilitateur-fr" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="agilitateur-fr" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">Agilitateur-fr</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><item>
    <title>Soft(ware)Ball</title>
    <link>http://agilitateur.azeau.com/post/2013/05/09/Soft%28ware%29Ball</link>
    <guid isPermaLink="false">urn:md5:ca8df7a0c3e77a8afd2cf4f7db8f6893</guid>
    <pubDate>Thu, 09 May 2013 19:42:00 +0200</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
            
    <description>    &lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/evenements/softwareball_v1.small.png" alt="Soft(ware)ball" style="float:right; margin: 0 0 1em 1em;" title="Soft(ware)ball" /&gt;&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;&lt;q&gt;Software development is a cooperative game of invention and communication&lt;/q&gt;&lt;/strong&gt;&lt;br /&gt;
J'en arrive à penser que cette phrase d'Alistair Cockburn définit l'essence du développement logiciel.&lt;/p&gt;


&lt;p&gt;Oui, développer un logiciel c'est jouer à un jeu.&lt;br /&gt;
Sans vouloir paraphraser &lt;a href="http://www.amazon.fr/gp/product/0321482751/ref=as_li_ss_tl?ie=UTF8&amp;amp;camp=1642&amp;amp;creative=19458&amp;amp;creativeASIN=0321482751&amp;amp;linkCode=as2&amp;amp;tag=lagilit-21"&gt;Agile Software Development: The Cooperative Game&lt;/a&gt; qui l'explique bien mieux que je ne pourrais le faire, le développement logiciel est un jeu coopératif dont l'objectif est de mettre en production un système.&lt;/p&gt;


&lt;p&gt;C'est réellement un &lt;a href="http://fr.wikipedia.org/wiki/Jeu_coop%C3%A9ratif_%28jeu%29"&gt;jeu coopératif&lt;/a&gt;, c'est à dire un jeu où &lt;q&gt;tous les joueurs gagnent ou perdent ensemble&lt;/q&gt;. Par tous les joueurs on entend les clients, les développeurs, etc. C'est d'ailleurs ce que nous rappelle &lt;a href="http://www.agilemanifesto.org/iso/fr/"&gt;le manifeste agile&lt;/a&gt;&amp;nbsp;: &lt;q&gt;&lt;strong&gt;la collaboration avec les clients&lt;/strong&gt; plus que la négociation contractuelle&lt;/q&gt;.&lt;/p&gt;


&lt;p&gt;Le développement logiciel est un jeu car son issue est incertaine. Même si on élabore une stratégie et que, plus localement, on fait appel à diverses tactiques, on ne peut gagner que par &lt;q&gt;&lt;strong&gt;l’adaptation au changement&lt;/strong&gt; plus que le suivi d’un plan&lt;/q&gt;.&lt;/p&gt;


&lt;p&gt;La communication entre les divers joueurs tient un rôle primordial. C'est pour cela que l'on valorise &lt;q&gt;&lt;strong&gt;les individus et leurs interactions&lt;/strong&gt; plus que les processus et les outils&lt;/q&gt;.&lt;/p&gt;


&lt;p&gt;Toutes ces notions sont importantes, et il n'est pas étonnant de voir aujourd'hui se développer leur apprentissage à travers le jeu. On joue à des jeux pour reproduire en quelques minutes ou en quelques heures les mêmes mécanismes de coopération, communication et adaptation au changement que l'on retrouve en grandeur réelle dans le jeu du développement logiciel.&lt;/p&gt;


&lt;p&gt;Soft(ware)Ball est un jeu qui s'inscrit dans cette lignée. Mais alors, pourquoi proposer un jeu de plus s'il en existe déjà tant ?&lt;br /&gt;
A cause de la valeur manquante du manifeste, celle qui met en avant &lt;strong&gt;le logiciel opérationnel&lt;/strong&gt;. La conception d'un logiciel implique l'invention et la combinaison de certains mécanismes. Même s'il y a une part importante de créativité dans certains jeux, celle-ci ne ressemble que rarement à celle mise en oeuvre dans le développement logiciel.&lt;/p&gt;


&lt;p&gt;Durant les trois dernières années, j'ai animé des ateliers &lt;q&gt;&lt;a href="http://agilitateur.azeau.com/post/2010/09/05/Stub-et-Mock-montent-sur-sc%C3%A8ne"&gt;Stub et Mock montent sur scène&lt;/a&gt;&lt;/q&gt; et &lt;q&gt;Si t'es pas SOLID, t'es pas agile&lt;/q&gt; pour faire découvrir certains principes et pratiques de développement logiciel. Ils avaient en commun le fait d'utiliser des "composants humains" pour assembler un logiciel. Cette approche a le double mérite de pouvoir faire de la programmation (et donc d'inventer des mécanismes) dans un temps relativement réduit et sans connaissance particulière d'un langage informatique.&lt;br /&gt;
Soft(ware)Ball reprend cette idée&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/05/09/#pnote-464-1" id="rev-pnote-464-1"&gt;1&lt;/a&gt;]&lt;/sup&gt; pour devenir &lt;strong&gt;un jeu coopératif de communication et d'invention&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;Vous pourrez découvrir Soft(ware)Ball (et surtout y jouer)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;En avant première, lors d'un &lt;a href="http://www.agiletoulouse.fr/ateliers/jeu-softwareball-jeudi-16-mai-2013"&gt;atelier organisé par Agile Toulouse&lt;/a&gt; le 16 mai 2013.&lt;/li&gt;
&lt;li&gt;A la &lt;a href="http://www.conference-agile.fr/"&gt;conférence Agile France&lt;/a&gt; à Paris les 23 et 24 mai 2013.&lt;/li&gt;
&lt;li&gt;Au &lt;a href="http://www.scrumgatheringparis.fr/"&gt;Scrum Gathering Paris&lt;/a&gt; les 23, 24 et 25 septembre 2013.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plus d'infos à propos du jeu seront ultérieurement disponibles sur &lt;a href="http://www.softwareball.org/"&gt;http://www.softwareball.org/&lt;/a&gt;&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/05/09/#rev-pnote-464-1" id="pnote-464-1"&gt;1&lt;/a&gt;] en fait, il reprend même le principe et les règles de &lt;q&gt;Si t'es pas SOLID, t'es pas agile&lt;/q&gt;&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2013/05/09/Soft%28ware%29Ball#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2013/05/09/Soft%28ware%29Ball#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/464</wfw:commentRss>
      </item>
    
  <item>
    <title>En revenant de Mix-IT 2013</title>
    <link>http://agilitateur.azeau.com/post/2013/04/29/En-revenant-de-Mix-IT-2013</link>
    <guid isPermaLink="false">urn:md5:9d68d08dcb3de5ac57ab8e3660275743</guid>
    <pubDate>Mon, 29 Apr 2013 15:05:00 +0200</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
            
    <description>    &lt;p&gt;&lt;a href="http://agilitateur.azeau.com/public/agilitateur/evenements/mixit2013.jpeg"&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/evenements/.mixit2013_s.jpg" alt="Miam" style="float:right; margin: 0 0 1em 1em;" title="Miam" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Jeudi et vendredi, j'étais à Lyon où j'ai, pour la première fois, participé à &lt;a href="http://agilitateur.azeau.com/post/2013/03/16/Mix-IT-2013"&gt;Mix-IT&lt;/a&gt;.&lt;br /&gt;
Merci aux organisateurs pour ces deux superbes journées.&lt;/p&gt;


&lt;h3&gt;Ce qui était bien, voire très bien&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Le parallèle entre le théâtre et le développement logiciel dans la session &lt;a href="http://www.mix-it.fr/session/277/collaborer-et-si-on-improvisait-"&gt;Collaborer, et si on improvisait?&lt;/a&gt; de &lt;a href="https://twitter.com/VincentDaviet"&gt;Vincent Daviet&lt;/a&gt;. Ce fut, sans le moindre doute, ma session préférée de ces deux jours. Tous les ingrédients étaient là pour transformer en une heure un groupe de personnes qui ne se connaissaient pas, ou peu, en une équipe soudée&amp;nbsp;: collaboration, communication, création, confiance...&lt;/li&gt;
&lt;li&gt;Les bonnes pratiques de &lt;a href="http://www.mix-it.fr/session/229/concevoir-son-developpement-par-l-api"&gt;conception d'une API web&lt;/a&gt; dans la session-débat animée par &lt;a href="https://twitter.com/davidbgk"&gt;David Larlet&lt;/a&gt; et &lt;a href="https://twitter.com/edasfr"&gt;Eric Daspet&lt;/a&gt;. Malgré une logistique peu adaptée, j'ai bien aimé la manière dont était menée la discussion avec cette mise en danger inévitable lorsqu'on donne à l'assistance la possibilité de s'exprimer longuement.&lt;/li&gt;
&lt;li&gt;Le rôle de l'architecte logiciel dans &lt;a href="http://www.mix-it.fr/session/129/software-architecture-for-developers"&gt;Software architecture for developers&lt;/a&gt; de &lt;a href="https://twitter.com/simonbrown"&gt;Simon Brown&lt;/a&gt;. Une session menée à un rythme incroyable. Même si je n'y ai pas appris grand chose, la description d'un architecte logiciel qui doit sortir de sa tour d'ivoire pour être sur le terrain fait toujours plaisir à entendre.&lt;/li&gt;
&lt;li&gt;L'importance de l'environnement pour faire une bon produit dans &lt;a href="http://www.mix-it.fr/session/125/the-product-is-the-byproduct"&gt;The product is the byproduct&lt;/a&gt; de &lt;a href="https://twitter.com/holman"&gt;Zach Holman&lt;/a&gt;. Une session très bien calibrée et sans grande surprise. La vision "de l'intérieur" de la société Github est intéressante. Est-ce que cette approche est transposable partout&amp;nbsp;? La question reste ouverte...&lt;/li&gt;
&lt;li&gt;La possibilité de &lt;a href="http://www.mix-it.fr/session/205/c-est-le-moment-de-se-lancer-dans-s-cas-la-"&gt;se lancer dans Scala&lt;/a&gt;. Dans cet atelier&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/29/#pnote-463-1" id="rev-pnote-463-1"&gt;1&lt;/a&gt;]&lt;/sup&gt; de &lt;a href="http://www.twitter.com/nivdul"&gt;Ludwine Probst&lt;/a&gt;, &lt;a href="http://www.twitter.com/jeanhelou"&gt;Jean Helou&lt;/a&gt; et &lt;a href="http://www.twitter.com/mchataigner"&gt;Mathieu Chataigner&lt;/a&gt;, j'ai pu découvrir les bases de la programmation fonctionnelle en Scala. Le nombre d'exercices proposés est conséquent. Il est difficile d'arriver aux exercices vraiment intéressants dans le peu de temps disponible mais &lt;a href="https://github.com/flatMapDuke/dans-s-cas-la-devoxx"&gt;on peut continuer à la maison&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;La session déjantée sur l'&lt;a href="http://www.mix-it.fr/session/319/apprendre-la-programmation"&gt;apprentissage de la programmation&lt;/a&gt; aux enfants. &lt;a href="http://www.twitter.com/Audrey_Neveu"&gt;Audrey Neveu&lt;/a&gt; et &lt;a href="http://www.twitter.com/bootis"&gt;Aline Paponaud&lt;/a&gt; ont conclu ces deux jours dans la bonne humeur. C'est un sujet important qui méritait une telle mise en avant. Paradoxalement, j'ai l'impression qu'il est plus difficile de se lancer dans la programmation qu'il y a 30 ans lorsque j'étais ado. A l'époque, programmer était presque un passage obligé même si on commençait par recopier du code sans le comprendre. Aujourd'hui, un ordinateur sait faire tant de choses "tout seul" qu'il en faut beaucoup plus pour montrer l'intérêt d'écrire un programme qui n'arrivera jamais à la cheville de ce qui est déjà là à portée de clic - et je parle ici en tant que père de trois filles qui ont déjà eu &lt;a href="http://scratch.mit.edu/"&gt;Scratch&lt;/a&gt; entre les mains.&lt;/li&gt;
&lt;li&gt;Les retours que j'ai eus pour &lt;a href="http://www.mix-it.fr/session/198/deux-ans-dans-le-flux"&gt;Deux ans dans le flux&lt;/a&gt;. Ma session a été extrêmement bien accueillie. Je remercie ici ceux qui ont tweeté tout le bien qu'ils en pensaient. S'il y en a qui veulent continuer à discuter de &lt;a href="http://agilitateur.azeau.com/post/2013/04/02/Qui-a-besoin-de-plusieurs-branches"&gt;branche unique&lt;/a&gt;, de prévisions probabilistes ou de quoi que ce soit d'autre, vous savez où me joindre&amp;nbsp;!&lt;/li&gt;
&lt;li&gt;L'accueil réservé aux orateurs. J'ai eu la chance de voir une partie de l'envers du décor et l'attention portée à ceux qui viennent pour seulement partager leurs connaissances et leurs expériences avec leurs pairs -c'est en tout cas comme ça que j'envisage les choses- était bien au delà de mes attentes.&lt;/li&gt;
&lt;li&gt;Les rencontres. C'est finalement le plus important&amp;nbsp;: créer des occasions d'échange entre personnes venues d'horizons variés&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/29/#pnote-463-2" id="rev-pnote-463-2"&gt;2&lt;/a&gt;]&lt;/sup&gt;. La chevauchée en &lt;a href="http://www.velov.grandlyon.com/"&gt;vélo'v&lt;/a&gt; dans les rues de Lyon à une heure du mat est une option recommandée.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Ce qui aurait pu être mieux&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La description des sessions. J'ai quelquefois été surpris par un contenu qui ne correspondait pas à l'idée que j'avais en tête en lisant la description. Au final, l'intérêt pour la session est toujours là mais on peut toujours faire mieux.&lt;/li&gt;
&lt;li&gt;Une meilleure logistique dans quelques cas bien précis&amp;nbsp;: la retransmission des keynotes dans la 2ème salle&amp;nbsp;; la sonorisation générale de l'ensemble. La mauvaise accoustique générale des salles et le ronronnement (des climatiseurs ?) imposait l'usage de micros qui n'étaient pas toujours au rendez-vous ni très bien réglés.&lt;/li&gt;
&lt;li&gt;Les cercles d'habitués qui ne favorisent pas les échanges. J'ai surtout ressenti cela lors de la soirée orateurs précédant l'évènement et durant la première journée. Après la soirée du jeudi, ça allait un peu mieux. L'existence de communautés "java" et "agile" réunies pour l'occasion n'est pas étrangère à cela. Il y a encore du boulot pour réellement décloisonner.&lt;/li&gt;
&lt;li&gt;L'obsession des détails techniques dans certaines sessions ou discussions. Je veux bien que le problème des "null pointer" dans java soit important mais de là à s'éterniser dessus... (on a du y passer près de 10 minutes dans la session sur Kotlin) J'ai l'impression que (en lien avec le point précédent) l'obsession inutile pour les détails techniques qui semble exister dans une partie de la communauté "java" n'a d'égale que la négligence pour ces mêmes détails dans une partie de la communauté "agile".&lt;/li&gt;
&lt;li&gt;Les hamburgers du Blogg qui mettent deux heures à arriver au lieu de la demi-heure annoncée.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Les questions (que je me suis) posées&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Au delà de proposer plusieurs paradigmes de programmation avec un langage unique, Scala permet-il de mixer les paradigmes pour que l'ensemble soit plus intéressant que la somme de chacun d'entre eux pris séparément&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Mais qu'est-ce qu'ils ont tous ces développeurs java à parler sans arrêt de Null Pointer Exception&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Comment faire comprendre l'intérêt de la branche unique de développement sans faire sauter au plafond la moitié de la salle&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Qu'est ce qu'une API&amp;nbsp;?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Les lecons (re-)apprises&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La distinction architecte/développeur ne devrait pas exister&lt;/li&gt;
&lt;li&gt;Toute activité assimilable à un jeu collaboratif de communication et d'invention a beaucoup de choses en commun avec le développement logiciel&lt;/li&gt;
&lt;li&gt;Une API web doit renvoyer des identifiants web. Il ne faut pas avoir de client spécifique pour les interpréter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les supports des diverses sessions et l'ensemble des compte-rendus &lt;a href="http://www.mix-it.fr/article/55/les-billets-apres-mix-it-2013"&gt;sont disponibles sur le site de l'évènement&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/29/#rev-pnote-463-1" id="pnote-463-1"&gt;1&lt;/a&gt;] pour faire bien il faut, en fait, dire "hands-on"&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/29/#rev-pnote-463-2" id="pnote-463-2"&gt;2&lt;/a&gt;] J'essaie de lister ici toutes les personnes avec lesquelles j'ai pu échanger quelques mots - et dont je me souviens du nom. Si vous n'y êtes pas, faites-le moi savoir ! &lt;a href="http://twitter.com/AlfredAlmendra"&gt;Alfred&lt;/a&gt;, &lt;a href="http://www.mix-it.fr/profile/kurichan"&gt;André&lt;/a&gt;, &lt;a href="http://twitter.com/avernois"&gt;Antoine&lt;/a&gt;, &lt;a href="http://twitter.com/CamilleRoux"&gt;Camille&lt;/a&gt;, &lt;a href="http://twitter.com/CarolineDamour"&gt;Caroline&lt;/a&gt;, &lt;a href="https://twitter.com/Xtof_Franco"&gt;Christophe&lt;/a&gt;, &lt;a href="https://twitter.com/ElleneSiber"&gt;Ellène&lt;/a&gt;, &lt;a href="https://twitter.com/EFranchomme"&gt;Emilie&lt;/a&gt;, &lt;a href="https://twitter.com/esiber"&gt;Eric&lt;/a&gt;, &lt;a href="https://twitter.com/evantill"&gt;Eric&lt;/a&gt;, &lt;a href="http://www.twitter.com/FranckDepierre"&gt;Franck&lt;/a&gt;, &lt;a href="http://twitter.com/guillaume_agile"&gt;Guillaume&lt;/a&gt;, &lt;a href="http://twitter.com/hguemar"&gt;Haïkel&lt;/a&gt;, &lt;a href="http://twitter.com/morlhon"&gt;Jean-Laurent&lt;/a&gt;, &lt;a href="https://twitter.com/jlrigau"&gt;Jean-Louis&lt;/a&gt;, &lt;a href="http://twitter.com/JeromeAvoustin"&gt;Jerôme&lt;/a&gt;, &lt;a href="https://twitter.com/jonathan_scher"&gt;Jonathan&lt;/a&gt;, &lt;a href="https://twitter.com/LaurentBristiel"&gt;Laurent&lt;/a&gt;, &lt;a href="http://twitter.com/lmorisseau"&gt;Laurent&lt;/a&gt;, &lt;a href="http://twitter.com/Armaklan"&gt;Lionel&lt;/a&gt;, &lt;a href="https://twitter.com/mjullien"&gt;Marianne&lt;/a&gt;, &lt;a href="https://twitter.com/Swiip"&gt;Matthieu&lt;/a&gt;, &lt;a href="https://twitter.com/njozwiak"&gt;Nicolas&lt;/a&gt;, &lt;a href="https://twitter.com/npelloux"&gt;Nicolas&lt;/a&gt;, &lt;a href="http://twitter.com/sanlaville"&gt;Rémy&lt;/a&gt;, &lt;a href="https://twitter.com/romaincouturier"&gt;Romain&lt;/a&gt;, &lt;a href="http://twitter.com/sarahhaim"&gt;Sarah&lt;/a&gt;, &lt;a href="http://twitter.com/langlois_s"&gt;Stéphane&lt;/a&gt;, &lt;a href="https://twitter.com/thierrycros"&gt;Thierry&lt;/a&gt;, &lt;a href="http://www.mix-it.fr/profile/ursula"&gt;Ursula&lt;/a&gt;, &lt;a href="http://twitter.com/xnopre"&gt;Xavier&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2013/04/29/En-revenant-de-Mix-IT-2013#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2013/04/29/En-revenant-de-Mix-IT-2013#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/463</wfw:commentRss>
      </item>
    
  <item>
    <title>Un code propre est plus utile qu'un code efficace</title>
    <link>http://agilitateur.azeau.com/post/2013/04/07/Un-code-propre-est-plus-utile-qu-un-code-efficace</link>
    <guid isPermaLink="false">urn:md5:4825121240e0955b716eea7274434e19</guid>
    <pubDate>Sun, 07 Apr 2013 14:44:00 +0200</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
            
    <description>    &lt;p&gt;Il fut un temps, avant que le développement de logiciels ne devienne mon métier, où la qualité d'un programme se jugeait, à mes yeux, à son efficacité&amp;nbsp;: rapidité d'exécution, faible occupation mémoire, compacité du code&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#pnote-462-1" id="rev-pnote-462-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;... Mais ça c'était avant. Je suis depuis longtemps convaincu que la clarté et la &lt;a href="http://agilitateur.azeau.com/post/2011/04/13/Avant-de-se-mettre-%C3%A0-%C3%A9crire%2C-il-faut-apprendre-%C3%A0-lire"&gt;lisibilité&lt;/a&gt; sont des critères incomparablement supérieurs.&lt;br /&gt;
Est-ce un changement de point de vue dû à l'expérience&amp;nbsp;?&lt;/p&gt;


&lt;p&gt;Dans une discussion sur le groupe google "Software Craftsmanship" intitulée &lt;a href="https://groups.google.com/d/msg/software_craftsmanship/YRUAFCANDMw/EdO-RPEfxQwJ"&gt;"Optimizing for code readability vs efficiency"&lt;/a&gt;, l'auteur initial explique que ses étudiants sont beaucoup plus attachés à l'efficacité et que faire passer le message d'une meilleure lisibilité n'est pas une tache aisée. Et pourtant, une meilleure lisibilité est souvent un passage obligé vers une meilleure efficacité comme le confirment plusieurs intervenants de la discussion.&lt;br /&gt;
Pourquoi ce message est-il si difficile à faire passer&amp;nbsp;?&lt;/p&gt;


&lt;p&gt;Je voudrais apporter ici ma pierre à l'édifice. Je suis parti d'un défi de programmation sur &lt;a href="http://www.codingame.com"&gt;codingame.com&lt;/a&gt;, celui de janvier 2013 nommé &lt;a href="http://www.codingame.com/challenge_janvier_2013_question3"&gt;"La résistance"&lt;/a&gt;&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#pnote-462-2" id="rev-pnote-462-2"&gt;2&lt;/a&gt;]&lt;/sup&gt;, et j'ai essayé de l'implémenter en pilotant mon développement par les tests, en favorisant la clarté de la conception et sans jamais essayer d'optimiser prématurément.&lt;/p&gt;


&lt;p&gt;Il s'agit de décoder un message en morse, potentiellement très long (plusieurs milliers de signes 'point' et 'tiret') et dont les séparateurs entre les mots ne sont pas connus. On dispose pour cela d'un lexique des mots possibles (là aussi potentiellement plusieurs milliers de mots différents). Et on s'attend bien évidemment à ce que ce décodage soit très rapide.&lt;br /&gt;
Une précision s'impose avant d'entrer dans le sujet. La résolution de ce problème nécessite un choix de stratégie algorithmique. Ce n'est pas le TDD qui va me faire découvrir comme par magie la bonne stratégie à adopter.&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#pnote-462-3" id="rev-pnote-462-3"&gt;3&lt;/a&gt;]&lt;/sup&gt; La création d'algorithmes, ça relève du domaine de &lt;a href="http://fr.wikipedia.org/wiki/Informatique_th%C3%A9orique"&gt;l'informatique théorique&lt;/a&gt;, pas du développement logiciel. Le TDD, lui, va me permettre d'implémenter le plus proprement possible l'approche que je choisirai.&lt;br /&gt;
Ceci étant acquis, mon choix se porte sur la stratégie la plus intuitive et faisant l'usage minimal de notions compliquées&amp;nbsp;: parcourir de gauche à droite le message morse en recherchant toutes les solutions possibles.&lt;/p&gt;


&lt;p&gt;Je commence par implémenter quelques &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/tests/ConvertTests.cs"&gt;fonctions&lt;/a&gt; &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/src/Convert.cs"&gt;utilitaires&lt;/a&gt; pour représenter une séquence morse et faire les conversions adéquates avec les chaînes de caractères. Rien de passionnant.&lt;br /&gt;
Le vrai boulot démarre en top-down. Je définis l'abstraction qui va me permettre de décoder un message morse&amp;nbsp;: renvoyer un ensemble de toutes les séquences de mots correspondant à un message morse donné.&lt;br /&gt;&lt;/p&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public enum Morse
{
  Dot,
  Dash
}

public interface IDecodeMessage
{
  IEnumerable&amp;lt;IEnumerable&amp;lt;string&gt;&gt; Decode (IEnumerable&amp;lt;Morse&gt; message);
}
&lt;/pre&gt;



&lt;p&gt;Je commence à piloter l'implémentation en utilisant les jeux de tests fournis par codingame.com. Il est important d'écrire les tests en utilisant des notions stables, en l'occurrence mes tests portent uniquement sur le contrat "I Decode Message" et ne font jamais appel à des détails d'implémentation. J'avais expliqué cette approche dans &lt;a href="http://agilitateur.azeau.com/post/2012/03/07/Chacun-cherche-son-TDD"&gt;"Chacun cherche son TDD"&lt;/a&gt;.&lt;br /&gt;
En faisant évoluer la méthode "Decode", je vois très rapidement un autre concept apparaître. C'est dû à l'aspect "organique" de la conception émergente (évoqué par ailleurs dans &lt;a href="http://agilitateur.azeau.com/post/2012/03/06/Le-logiciel%2C-un-organisme-multicellulaire"&gt;"Le logiciel, un organisme multicellulaire ?"&lt;/a&gt;). Une opération élémentaire de mon implémentation consiste à rechercher tous les mots du dictionnaire qui sont des candidats potentiels pour débuter une séquence morse donnée. Cette opération devient donc un contrat "I Find Words" dont l'implémentation sera découplée du décodage.&lt;br /&gt;
A cet instant je me retrouve avec un jeu d'interfaces qui restera stable pour le reste du développement (mais ça je ne le saurai qu'à la fin) :&lt;br /&gt;&lt;/p&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public interface IDecodeMessage
{
  IEnumerable&amp;lt;IEnumerable&amp;lt;string&gt;&gt; Decode (IEnumerable&amp;lt;Morse&gt; message, IFindWords thesaurus); 
  long Count (IEnumerable&amp;lt;Morse&gt; message, IFindWords thesaurus);
}

public struct Starting
{
  public string Word;
  public int MorseLength;
}
  
public interface IFindWords
{
  IEnumerable&amp;lt;Starting&gt; GetWordsStarting (IEnumerable&amp;lt;Morse&gt; sequence);
}
&lt;/pre&gt;



&lt;p&gt;On notera deux choses&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;J'ai rajouté une méthode "Count" dans "I Decode Message". L'énoncé du défi ne porte que sur la détermination du nombre de solutions. Toutefois, dans la vraie vie, on sera plus intéressé par les résultats du décodage. Je fais donc le choix d'implémenter les deux aspects du problème.&lt;/li&gt;
&lt;li&gt;La méthode "GetWordsStarting" du contrat "I Find Words" renvoie l'ensemble des mots qui pourraient se trouver au début de la séquence de morse donnée. Pour chacun de ces mots, elle renvoie aussi le nombre de signaux morse consommés dans la séquence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A partir de là il faut faire un choix de priorité&amp;nbsp;: continuer sur l'implémentation du décodage ou se focaliser sur la recherche de mots.&lt;br /&gt;
Je choisis une solution intermédiaire. Je vais écrire une implémentation simpliste de "I Find Words". Si elle est assez efficace, tant mieux, sinon elle me servira de &lt;a href="http://xunitpatterns.com/Fake%20Object.html"&gt;fake&lt;/a&gt; pour écrire le décodage.&lt;br /&gt;
Je transforme ma panoplie de tests pour en créer une &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/tests/IFindWordsTests.cs"&gt;adaptée à "I Find Words"&lt;/a&gt; et j'écris une &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/src/DumbThesaurus.cs"&gt;implémentation basique&lt;/a&gt;. Elle contient la liste des mots du dictionnaire et, pour chacun d'entre eux, la chaîne de caractères correspondant au code morse. A chaque appel de "GetWordsStarting", la liste entière est parcourue et les mots sont détectés par simple comparaison de chaînes de caractères morse. On peut sûrement faire plus efficace mais c'est simple et ça fonctionne - et c'est tout ce qui m'importe pour l'instant.&lt;/p&gt;


&lt;p&gt;Je peux alors attaquer la partie décodage. A partir du &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/tests/IDecodeMessageTests.cs"&gt;jeu de tests initié précédemment&lt;/a&gt;, j'écris &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/src/DeepSearchDecoder.cs"&gt;un décodeur qui procède par recherche en profondeur&lt;/a&gt;. Un curseur définit la profondeur courante et des appels récursifs permettent d'explorer les profondeurs suivantes. Un &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/src/DeepSearchStrategy.cs"&gt;mécanisme de typage générique&lt;/a&gt; me permet de factoriser le code de recherche qui est désormais commun au décodage complet et à leur simple dénombrement.&lt;/p&gt;

&lt;pre&gt;
Exemple : ......-...-..---.-----.-..-..-.. avec les mots HELL, HELLO, OWORLD, WORLD

Niveau 1
| ......-...-..---.-----.-..-..-..
| H   EL   L       ==&amp;gt; 2a
| H   EL   L   O   ==&amp;gt; 2b

Niveau 2a
| ......-...-.. | ---.-----.-..-..-..
| H   EL   L    | O  W  O  R  L   D

Niveau 2b
| ......-...-..--- | .-----.-..-..-..
| H   EL   L   O   | W  O  R  L   D
&lt;/pre&gt;


&lt;p&gt;Sur des petits tests, tout cela fonctionne parfaitement. Cela se complique lorsque j'écris un test qui dénombre 65536 solutions car celui-ci prend près de 4 secondes pour sortir le résultat. J'ai deux pistes possibles d'optimisation&amp;nbsp;: la recherche des mots ou le parcours en profondeur.&lt;br /&gt;
Je choisis de rester sur ce dernier car il me vient l'idée de mémoriser les résultats obtenus pour éviter de nombreux appels récursifs&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#pnote-462-4" id="rev-pnote-462-4"&gt;4&lt;/a&gt;]&lt;/sup&gt;. Pour cela j'écris une classe d'implémentation différente pour le même contrat "I Decode Message" mais cette fois &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/src/CachedDeepSearchDecoder.cs"&gt;en ajoutant un mécanisme de cache&lt;/a&gt;. Au fil de l'écriture, j'arriverai à mettre en commun une majorité de code entre les deux implémentations de parcours en profondeur.&lt;/p&gt;


&lt;p&gt;Ce choix fait des merveilles. Le test qui passait en 4 secondes&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#pnote-462-5" id="rev-pnote-462-5"&gt;5&lt;/a&gt;]&lt;/sup&gt; tombe à 35 millisecondes&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#pnote-462-6" id="rev-pnote-462-6"&gt;6&lt;/a&gt;]&lt;/sup&gt;. Je peux alors attaquer le plus gros test fourni par le défi. Il contient un dictionnaire d'environ 10000 mots et il demande le décodage d'une séquence morse d'environ 10000 signes pour trouver un total de 57330892800 combinaisons.&lt;br /&gt;
Et là c'est la claque&amp;nbsp;: le test passe en plus de 40 secondes. Heureusement que je n'ai pas commencé par ce test avec l'implémentation sans cache car elle serait probablement encore en train de tourner...&lt;/p&gt;


&lt;p&gt;Il me reste une dernière piste d'amélioration&amp;nbsp;: la recherche de mots. J'essaie d'utiliser une structure de donnée classique lorsqu'on veut avoir des recherches plus rapides&amp;nbsp;: l'arbre.&lt;br /&gt;
Comme le montre le diagramme ci-dessous, je place les mots du dictionnaire dans une structure où, en partant de la racine, peuvent être rapidement trouvés tous les mots commençant une séquence de morse donnée. Par exemple, une séquence "dash dot" me donnera les mots "T", "TE" et "N" (s'ils font partie du dictionnaire, bien évidemment).
&lt;img src="http://agilitateur.azeau.com/public/agilitateur/resistance/Resistance_Tree.png" alt="Arbre" style="display:block; margin:0 auto;" title="Arbre" /&gt;&lt;/p&gt;


&lt;p&gt;Ce &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/src/TreeThesaurus.cs"&gt;dictionnaire en arbre&lt;/a&gt; est donc une implémentation alternative de "I Find Words".&lt;br /&gt;
Et le test qui prenait plus de 40 secondes&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#pnote-462-7" id="rev-pnote-462-7"&gt;7&lt;/a&gt;]&lt;/sup&gt; tombe à 130 millisecondes&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#pnote-462-8" id="rev-pnote-462-8"&gt;8&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;La démarche et les chiffres parlent d'eux-mêmes.&lt;br /&gt;
Une stratégie algorithmique étant fixée, le TDD et une approche du code systématiquement claire et lisible mettent en évidence les concepts importants d'un logiciel. Et en se basant sur ces concepts et les tests qui y sont associés, on peut bâtir, lorsqu'elle devient nécessaire, une stratégie d'optimisation pour rendre le logiciel plus efficace.&lt;br /&gt;
Cette approche est d'autant plus importante que&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;ins&gt;un logiciel évolue rarement dans un environnement figé&lt;/ins&gt;. Dans l'exemple que l'on vient de voir, on pourrait, par exemple, imaginer un dictionnaire initialement chargé en mémoire à partir d'un fichier qui, du fait de sa mise à jour continuelle, évolue en un dictionnaire stocké dans une base de données. L'implémentation de "I Find Words" serait alors spécifique à notre base de données et indépendante des avancées réalisées sur la partie parcours en profondeur.&lt;/li&gt;
&lt;li&gt;&lt;ins&gt;un logiciel n'a que rarement des fonctionnalités immuables&lt;/ins&gt;. Toujours dans le logiciel ici présent, on pourrait imaginer un décodage des phrases qui tiendrait compte d'un contexte sémantique (par exemple, tel mot ne peut pas être suivi de tel ou tel autre mot). Là encore, il faudrait envisager des modifications qui seront d'autant plus aisées que les composants présents sont faiblement couplés.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;ins&gt;Ecrire un logiciel ce n'est pas écrire un algorithme&lt;/ins&gt;. On a besoin des fondements théoriques que la science informatique peut nous apporter sur les divers types d'algorithmes, sur leur complexité... Mais &lt;ins&gt;écrire un logiciel c'est se placer dans un contexte mouvant en vue de réaliser et faire évoluer un produit pour un utilisateur&lt;/ins&gt;.&lt;br /&gt;
La plupart du temps cela nécessite de donner la priorité absolue à la maintenabilité du code. Il faut donc le garder propre car, dans la durée, c'est le seul moyen pour qu'il reste efficace.&lt;/p&gt;


&lt;p&gt;Le code source complet en C# utilisé dans le billet est disponible sur github à l'adresse &lt;a href="https://github.com/Oaz/Resistance/tree/code_propre"&gt;https://github.com/Oaz/Resistance/tree/code_propre&lt;/a&gt;.&lt;br /&gt;
Le schéma ci-dessous présente les principales interfaces et classes de ce code source.
&lt;a href="http://agilitateur.azeau.com/public/agilitateur/resistance/Resistance_UML.png"&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/resistance/.Resistance_UML_m.jpg" alt="UML" style="display:block; margin:0 auto;" title="UML" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#rev-pnote-462-1" id="pnote-462-1"&gt;1&lt;/a&gt;] A titre d'exemple, voici un &lt;a href="http://download.abandonware.org/magazines/Hebdogiciel/hebdogiciel_numero118/12.jpg"&gt;bout de code écrit en 1985&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#rev-pnote-462-2" id="pnote-462-2"&gt;2&lt;/a&gt;] Merci à &lt;a href="https://twitter.com/JeromeAvoustin"&gt;Jérôme&lt;/a&gt; pour m'en avoir indirectement &lt;a href="https://twitter.com/JeromeAvoustin/status/318109335790182402"&gt;donné l'idée&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#rev-pnote-462-3" id="pnote-462-3"&gt;3&lt;/a&gt;] Rappelons-nous &lt;a href="http://www.infoq.com/news/2007/05/tdd-sudoku"&gt;cette comparaison&lt;/a&gt; entre le TDD de Ron Jeffries et le code (difficile à lire et impossible à maintenir) de Peter Norvig qui utilise une toute autre approche pour résoudre un sudoku.&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#rev-pnote-462-4" id="pnote-462-4"&gt;4&lt;/a&gt;] un langage de programmation qui se rendrait compte que je n'utilise que des fonctions pures et des objets non mutables m'aurait peut être évité cette étape car il ne relancerait pas le calcul d'une même fonction avec les mêmes paramètres&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#rev-pnote-462-5" id="pnote-462-5"&gt;5&lt;/a&gt;] voir test &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/tests/IDecodeMessageTests.cs"&gt;DeepSearch/3c/Dumb&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#rev-pnote-462-6" id="pnote-462-6"&gt;6&lt;/a&gt;] voir test &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/tests/IDecodeMessageTests.cs"&gt;CachedDeepSearch/3c/Dumb&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#rev-pnote-462-7" id="pnote-462-7"&gt;7&lt;/a&gt;] voir test &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/tests/IDecodeMessageTests.cs"&gt;CachedDeepSearch/4/Dumb&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/07/#rev-pnote-462-8" id="pnote-462-8"&gt;8&lt;/a&gt;] voir test &lt;a href="https://github.com/Oaz/Resistance/blob/code_propre/tests/IDecodeMessageTests.cs"&gt;CachedDeepSearch/4/Tree&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2013/04/07/Un-code-propre-est-plus-utile-qu-un-code-efficace#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2013/04/07/Un-code-propre-est-plus-utile-qu-un-code-efficace#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/462</wfw:commentRss>
      </item>
    
  <item>
    <title>Qui a besoin de plusieurs branches ?</title>
    <link>http://agilitateur.azeau.com/post/2013/04/02/Qui-a-besoin-de-plusieurs-branches</link>
    <guid isPermaLink="false">urn:md5:8b3d7c91a9340e918a4748a6ec331299</guid>
    <pubDate>Tue, 02 Apr 2013 07:59:00 +0200</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
            
    <description>    &lt;p&gt;&lt;a href="http://commons.wikimedia.org/wiki/File:Turdus_pilaris_Schwarm_2011.JPG"&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/180px-Turdus_pilaris_Schwarm_2011.JPG" alt="à part peut être les grives" style="float:right; margin: 0 0 1em 1em;" title="à part peut être les grives" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Si les &lt;a href="http://fr.wikipedia.org/wiki/Logiciel_de_gestion_de_versions"&gt;logiciels de gestion de versions&lt;/a&gt; sont globalement rentrés dans les habitudes de tout développement logiciel, la façon de les utiliser est loin d'être uniforme. Cette multiplicité des usages est particulièrement flagrante lorsque l'on évoque la notion de &lt;em&gt;branches&lt;/em&gt;.&lt;br /&gt;
Wikipedia &lt;a href="http://fr.wikipedia.org/wiki/Gestion_de_versions#Branches"&gt;définit ainsi&lt;/a&gt; les branches&amp;nbsp;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Lorsque des modifications divergentes interviennent hors conflit, il se crée des branches. Le fait de vouloir rassembler deux branches est une fusion de branches.&lt;/p&gt;
&lt;p&gt;
Les branches sont utilisées pour permettre :&lt;br /&gt;
la maintenance d'anciennes versions du logiciel (sur les branches) tout en continuant le développement des futures versions (sur le tronc) ;&lt;br /&gt;
le développement parallèle de plusieurs fonctionnalités volumineuses sans bloquer le travail quotidien sur les autres fonctionnalités.&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;La nécessité de maintenir plusieurs versions livrées d'un même logiciel est un besoin courant dès que le logiciel est proposé à plusieurs clients .Un nouveau client est intéressé par la version 4.0 qui vient tout juste de sortir tandis qu'un autre préfére rester sur la 3.2 sur laquelle il a investi beaucoup de temps de formation. Le coût de passage à une nouvelle version majeure serait prohibitif. Du coup l'équipe de développement doit simultanément développer la version courante et corriger les bugs trouvés sur des versions plus anciennes. Pour cela, on travaille avec des &lt;em&gt;release branches&lt;/em&gt;.&lt;br /&gt;
Par ailleurs, le développement d'une fonctionnalité ne peut pas se faire du jour au lendemain. Cette même équipe, en développant la version 4.0 ne peut pas se contenter de ne travailler que sur les fonctionnalités en cours. Il y a cette future fonctionnalité que tant de clients attendent et qui sortira, si tout va bien, dans la version 4.5 ou, au pire, l'an prochain dans la 5.0. Et cette fonctionnalité prend tant de temps à mettre en oeuvre qu'il faut d'ores et déjà y travailler. Mais on ne peut pas le faire sur la version courante. On va donc utiliser une &lt;em&gt;feature branch&lt;/em&gt; qui sera fusionnée ultérieurement avec la version courante du moment.&lt;/p&gt;


&lt;p&gt;Ce scénario vous semble familier ?&lt;br /&gt;
C'est le lot de nombreuses équipes pour qui le contrôle de version est devenu une des pierres angulaires de leur processus de développement et occupe une part non négligeable de leur activité quotidienne.&lt;/p&gt;


&lt;p&gt;L'émergence récente des outils de gestion de version décentralisés facilite grandement la tache de ces équipes.&lt;br /&gt;
Historiquement, avec les gestions de version centralisées, les branches sont coûteuses. Il faut demander au serveur de créer une branche, ce qu'il va faire en copiant plus ou moins intelligemment les données d'un dossier dans un autre dossier. En fait, dans une approche centralisée, diverger du point central est l'exception. On s'attend à ce que le développeur rapporte au plus vite sa production sur le serveur et résolve les conflits pouvant intervenir avec la production des autres développeurs.&lt;br /&gt;
Dans les outils décentralisés, les branches sont en quelque sorte incluse dans l'ADN. On s'attend à ce que des divergences surviennent et on met en place les fonctionnalités permettant de les fusionner au mieux, de piocher ici ou là des modifications individuelles. Bref on n'a pas peur des branches et on les accueille avec plaisir.&lt;/p&gt;


&lt;p&gt;Sauf que...&lt;br /&gt;
Comme disait l'autre, si ton seul outil est un marteau, tu verras tous les problèmes comme des clous...&lt;br /&gt;
J'ai la désagréable impression que, les outils décentralisés ayant le vent en poupe dans les usages, l'utilisation à outrance de branches pour la moindre raison devrait aller de soi parce que c'est devenu si simple de les manipuler...&lt;br /&gt;
On ne peut nier que &lt;a href="http://www.youtube.com/watch?v=4XpnKHJAok8"&gt;Linus Torvalds ait besoin de git&lt;/a&gt; parce qu'il travaille indirectement avec des centaines de personnes et qu'il ne fait confiance&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/02/#pnote-461-1" id="rev-pnote-461-1"&gt;1&lt;/a&gt;]&lt;/sup&gt; à quasiment aucune d'entre elles. Le modèle décentralisé semble la réponse idéale aux gros projets open source.&lt;br /&gt;
Mais qui a des besoins vaguement similaires&amp;nbsp;?&lt;/p&gt;


&lt;p&gt;Les branches de release ne sont pas une fatalité. Un logiciel peut évoluer jour après jour sans véritable version majeure en étant continuellement livré à ses clients. Si certaines fonctionnalité sont trop dures à avaler immédiatement, on imagine des mécanismes de configuration pour les activer à la demande.&lt;br /&gt;
Les branches de feature ne sont pas une fatalité. Les mêmes mécanismes de configuration sont utilisés pour des fonctionnalité non terminées&amp;nbsp;: leur code sera présent mais non exécuté dans la version livrée.&lt;/p&gt;


&lt;p&gt;Pourquoi mettre tout son effort dans l'utilisation avancée d'un gestionnaire de version pour atteindre ces objectifs alors que la richesse des langages de développement nous permet de réaliser la même chose à l'intérieur du logiciel lui-même ?&lt;br /&gt;
On parle de plus en plus de &lt;em&gt;feature flipping&lt;/em&gt;, c'est à dire de la capacité à activer/désactiver une fonctionnalité via une option configuration. Mais je crois que ceci n'est que la partie émergée de l'iceberg à venir.&lt;br /&gt;
Un flag de configuration qui induit une armée de "ifs" à divers endroits du code en fonction de la fonctionnalité à maintenir n'ira jamais bien loin. Diverses techniques permettent toutefois de &lt;a href="http://www.antiifcampaign.com/"&gt;se débarrasser des ifs&lt;/a&gt;. On peut arriver à un &lt;em&gt;feature swapping&lt;/em&gt; extrêmement maintenable avec du polymorphisme et de l'injection de dépendance.&lt;br /&gt;
Bref, une meilleure approche de la conception logicielle rend le concept de branche obsolète.&lt;/p&gt;


&lt;p&gt;Mais on peut aller plus loin.&lt;br /&gt;
Dans une équipe agile, donc à taille humaine, où la confiance est inconditionnelle et où l'on pratique sans relâche la propriété collective de code, les feature branches n'ont pas d'intérêt car tout le monde travaille sur la même chose avec des échéances très courtes. Tous les membres de l'équipe modifient donc plusieurs fois par jour &lt;ins&gt;la&lt;/ins&gt; version de référence du logiciel.&lt;br /&gt;
Si on englobe dans le concept les utilisateurs du logiciel, on laisse également tomber les release branches car l'utilisateur n'a que faire de l'existence de plusieurs versions. Il veut seulement utiliser facilement et rapidement la meilleure version qui soit.&lt;/p&gt;


&lt;p&gt;Dans mon équipe, la &lt;ins&gt;&lt;em&gt;branche unique&lt;/em&gt;&lt;/ins&gt; est devenue un facteur important qui nous permet de développer sereinement et continuellement notre logiciel depuis plusieurs années. C'est ce dont je parlerai, entre autres choses, dans la session &lt;a href="http://www.mix-it.fr/session/198/deux-ans-dans-le-flux"&gt;"Deux ans dans le flux"&lt;/a&gt; lors du &lt;a href="http://www.mix-it.fr/"&gt;prochain Mix-IT&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/04/02/#rev-pnote-461-1" id="pnote-461-1"&gt;1&lt;/a&gt;]  peut être à juste titre mais c'est une autre histoire&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2013/04/02/Qui-a-besoin-de-plusieurs-branches#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2013/04/02/Qui-a-besoin-de-plusieurs-branches#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/461</wfw:commentRss>
      </item>
    
  <item>
    <title>Mix-IT 2013</title>
    <link>http://agilitateur.azeau.com/post/2013/03/16/Mix-IT-2013</link>
    <guid isPermaLink="false">urn:md5:ed5cd83540eb3685a788d542f260c11c</guid>
    <pubDate>Sat, 16 Mar 2013 18:34:00 +0100</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
            
    <description>    &lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/evenements/.logo-mixit_s.jpg" alt="Mix-IT 2013" style="float:right; margin: 0 0 1em 1em;" title="Mix-IT 2013" /&gt;
Les 25 et 26 avril prochains se déroulera à Lyon &lt;a href="http://www.mix-it.fr/"&gt;la 3ème édition de Mix-IT&lt;/a&gt;.&lt;br /&gt;
Et je suis très content de pouvoir, pour la première fois, y assister car je suis persuadé que c'est exactement le genre d'évènement dont a besoin le monde du développement logiciel.&lt;/p&gt;


&lt;p&gt;Il existe des évènements très orientés technique sur tel ou telle langage ou technologie (logiciel libre, microsoft, web, java...) Il en existe d'autres sur les aspects organisationnels du développement logiciel, avec nombre d'entre eux dédiés à l'agilité. Les frontières ne sont bien évidemment pas hermétiques&amp;nbsp;: on trouvera toujours quelques sessions parlant de méthodes agiles à DevoxxFR ou aux Tech Days tout comme on trouvera quelques ateliers où l'on écrit du code dans l'Agile Tour. Mais deux jours de conférences et ateliers où l'on trouve un certain équilibre entre tous les aspects du développement logiciel, je crois que ça reste unique en France &lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/03/16/#pnote-460-1" id="rev-pnote-460-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;.&lt;br /&gt;
Le développement logiciel est une discipline où l'on ne peut pas se contenter de maîtriser à fond les technos sans avoir conscience du &lt;a href="http://agilitateur.azeau.com/post/2011/04/13/Avant-de-se-mettre-%C3%A0-%C3%A9crire%2C-il-faut-apprendre-%C3%A0-lire"&gt;rôle essentiel que joue l'aspect humain&lt;/a&gt;. C'est aussi une discipline où, même si on n'est pas développeur, on ne peut pas se permettre &lt;a href="http://agilitateur.azeau.com/post/2011/03/13/Si-t%E2%80%99es-pas-codeur%2C-t%E2%80%99es-pas-producteur-de-logiciels"&gt;d'être ignare sur ce qu'est le code&lt;/a&gt;.  Ce sera un plaisir d'aller à une conférence sans être obligé de laisser la moitié du cerveau à la maison...&lt;/p&gt;


&lt;p&gt;La cerise sur le gâteau, c'est que, sachant que j'allais assister à Mix-IT 2013, j'ai proposé deux sessions et &lt;a href="http://www.mix-it.fr/session/198/deux-ans-dans-le-flux"&gt;l'une d'entre elles a été retenue&lt;/a&gt;. \o/&lt;/p&gt;


&lt;p&gt;Et, puisque &lt;a href="http://www.mix-it.fr/mixit13/planning"&gt;le planning est sorti&lt;/a&gt;, je suis allé y jeter un coup d'oeil pour commencer à faire quelques choix.&lt;/p&gt;


&lt;p&gt;Jeudi.&lt;br /&gt;
A 9h30, je me laisserais bien tenter par un &lt;a href="http://www.mix-it.fr/session/265/que-je-decoupe-ma-demande-en-petits-morceaux-"&gt;découpage en petits morceaux&lt;/a&gt; mais je ne suis pas sûr d'avoir envie d'attaquer directement avec un atelier. Il y a aussi le &lt;a href="http://www.mix-it.fr/session/150/why-kotlin-"&gt;langage Kotlin&lt;/a&gt; qui retient mon attention parce que je n'ai pas encore trouvé de langage qui me permette de prendre une JVM sans regretter mon C# préféré. A 11h00, il y a ce &lt;a href="http://www.mix-it.fr/session/133/validated-influencing"&gt;"Validated Influencing"&lt;/a&gt; qui m'intrigue. Je pourrais aussi &lt;a href="http://www.mix-it.fr/session/154/dive-into-kotlin"&gt;plonger dans Kotlin&lt;/a&gt; mais je compte voyager léger, donc sans laptop.&lt;br /&gt;
A 13h30, la question &lt;a href="http://www.mix-it.fr/session/198/deux-ans-dans-le-flux"&gt;ne se pose pas&lt;/a&gt;. A 15h00, non plus. J'ai eu l'occasion de voir la première d'&lt;a href="http://www.mix-it.fr/session/228/agile-unlimited"&gt;Agile Unlimited&lt;/a&gt; l'an dernier à &lt;a href="http://agilitateur.azeau.com/post/2012/10/28/Agile-Tour-Toulouse-2012%2C-entre-c%C3%A2linoth%C3%A9rapie-et-WTFs"&gt;Agile Toulouse&lt;/a&gt; donc, pour ce créneau horaire, je choisis sans hésiter &lt;a href="http://www.mix-it.fr/session/149/live-coding-avec-yeoman-angularjs"&gt;un live coding&lt;/a&gt; qui pourrait peut être me permettre de satisfaire un besoin que j'ai à court terme.&lt;br /&gt;
A 16h30, c'est le premier moment de la journée où aucune session ne m'attire plus particulièrement qu'une autre... Je verrai en fonction de l'humeur du moment. Par contre, à 18h00, le choix est déjà fait&amp;nbsp;: ce sera le &lt;a href="http://www.mix-it.fr/session/229/concevoir-son-developpement-par-l-api"&gt;développement piloté par l'API&lt;/a&gt; (car j'ai en tête un embryon de conférence sur un sujet connexe). L'&lt;a href="http://www.mix-it.fr/session/271/the-clean-architecture"&gt;architecture agile&lt;/a&gt; m'intéresse également mais je pourrai probablement la revoir du côté de Toulouse ou pas loin.&lt;/p&gt;


&lt;p&gt;Vendredi.&lt;br /&gt;
J'ai bien envie de démarrer la journée avec &lt;a href="http://www.mix-it.fr/session/277/collaborer-et-si-on-improvisait-"&gt;du théâtre&lt;/a&gt; parce que je n'avais pas pu assister à cet atelier à Agile Grenoble (et ses 9 tracks en parallèle...) et de la poursuivre avec &lt;a href="http://www.mix-it.fr/session/270/pour-un-management-vraiment-agile"&gt;un management vraiment agile&lt;/a&gt; parce que la tentation du command &amp;amp; control plane toujours.&lt;br /&gt;
Après le repas, j'essaierai d'aller faire quelques &lt;a href="http://www.mix-it.fr/session/130/agile-software-architecture-sketches"&gt;dessins d'architecture logicielle&lt;/a&gt;. Je suis curieux de voir comment formaliser des schémas en abandonnant UML.&lt;br /&gt;
A 15h, j'irai découvrir &lt;a href="http://www.mix-it.fr/session/126/the-hitchhikers-guide-to-uxing-without-a-uxer"&gt;comment faire de l'UX sans UXer&lt;/a&gt;, ce qui tombe plutôt bien car il n'y a pas vraiment de compétence UX dans notre équipe... Et pour finir la journée j'irai peut être participer au &lt;a href="http://www.mix-it.fr/session/146/challenge-kanban"&gt;Challenge Kanban&lt;/a&gt;, à moins que je ne me laisse tenter par le &lt;a href="http://www.mix-it.fr/session/175/entrer-dans-le-monde-du-robot-nao"&gt;robot Nao&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;Bref, j'ai déjà hâte d'y être.&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2013/03/16/#rev-pnote-460-1" id="pnote-460-1"&gt;1&lt;/a&gt;] les commentaires sont là pour me contredire le cas échéant&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2013/03/16/Mix-IT-2013#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2013/03/16/Mix-IT-2013#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/460</wfw:commentRss>
      </item>
    
  <item>
    <title>Agile Grenoble 2012, ma journée chez les binômes</title>
    <link>http://agilitateur.azeau.com/post/2012/11/10/Agile-Grenoble-2012%2C-ma-journ%C3%A9e-chez-les-bin%C3%B4mes</link>
    <guid isPermaLink="false">urn:md5:3dc8a24a6fed85cc59bb8e9a74cff484</guid>
    <pubDate>Sat, 10 Nov 2012 10:22:00 +0100</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
            
    <description>    &lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/evenements/binomes.png" alt="Binômes" style="float:right; margin: 0 0 1em 1em;" title="Binômes" /&gt;&lt;/p&gt;


&lt;p&gt;J'assistais jeudi pour la première fois à &lt;a href="http://2012.agile-grenoble.org"&gt;Agile Grenoble&lt;/a&gt;.&lt;/p&gt;


&lt;h3&gt;Ce qui était bien&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Le binôme &lt;a href="https://twitter.com/sanlaville"&gt;Rémy Sanlaville&lt;/a&gt;/&lt;a href="https://twitter.com/johan_alps"&gt;Johan Martinsson&lt;/a&gt; et leur refactoring du &lt;a href="http://iamnotmyself.com/2011/02/13/refactor-this-the-gilded-rose-kata/"&gt;Gilded Rose Kata&lt;/a&gt; chez les développeurs anonymes. Près de 70 personnes dans une salle prévue pour 40 (ne jamais sous-estimer l'attrait d'une session pour développeurs) et un public assez enthousiaste comme l'indiquait &lt;a href="https://twitter.com/sanlaville/status/266810192761597952"&gt;le ROTI&lt;/a&gt; à la sortie de la salle.&lt;/li&gt;
&lt;li&gt;Le binôme Emmanuel Gaillot/&lt;a href="https://twitter.com/jonathanperret"&gt;Jonathan Perret&lt;/a&gt; pour leur évocation des travers du pair programming. Là encore la (même) salle est plus que comble même si le public semble avoir moins accroché. Pour ma part, je me suis régalé. Il fallait peut-être avoir un minimum de recul sur la pratique pour apprécier pleinement la session contrairement à la précédente qui pouvait mieux parler à tous les développeurs&amp;nbsp;? Et j'en profite pour souhaiter une bonne continuation à &lt;a href="http://ut7.fr/"&gt;ut7&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Le binôme &lt;a href="https://twitter.com/cgrand"&gt;Christophe Grand&lt;/a&gt;/&lt;a href="https://twitter.com/petitlaurent"&gt;Laurent Petit&lt;/a&gt; et leur introduction au langage Clojure. J'ai trouvé le rythme de la session un peu trop lent à mon goût mais je suis très content d'y avoir participé car je ne connaissais pas du tout le langage. Et, surtout, je n'ai pas été surpris par leur style de conception ce qui me conforte dans mon approche pour l'instant très limitée des langages fonctionnels.&lt;/li&gt;
&lt;li&gt;La keynote de &lt;a href="https://twitter.com/gojkoadzic"&gt;Gojko Adzic&lt;/a&gt;. Elle n'apportait rien de fondamental pour qui a lu quelques uns de ses articles mais elle faisait plaisir à voir. Une &lt;ins&gt;vraie&lt;/ins&gt; keynote&amp;nbsp;: des idées fortes, un rythme soutenu, quelques exemples biens choisis, bref, un bon moment.&lt;/li&gt;
&lt;li&gt;La logistique. Un vestiaire qui m'a bien dépanné. Un repas bien au dessus de ce que l'on a à Agile Tour Toulouse et pour, parait-il, un coût moindre...&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Ce qui était moins bien&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Le nombre de sessions en parallèle. Neuf, c'est définitivement beaucoup trop pour ce genre de conférence où il est généralement difficile de se faire une idée du contenu exact des sessions. Et, le pire, c'est qu'il n'y avait absolument aucune classification ou thématique associée à chaque session. Bref, un vrai labyrinthe. Je me suis rabattu sur ce qui m'avait l'air le plus technique possible pour éviter de perdre mon temps.&lt;/li&gt;
&lt;li&gt;Un retour d'expérience de la Société Générale déguisé en keynote pour débuter l'après-midi. Ca a sûrement intéressé des gens mais de là à l'imposer à tout le monde... En plus impossible pour moi de sortir sans faire se lever 5 ou 6 personnes...&lt;/li&gt;
&lt;li&gt;Le retour d'expérience de &lt;a href="https://twitter.com/bangalaurent"&gt;Laurent Sarazzin&lt;/a&gt; (celui de la keynote subie donc). Tant qu'à être là j'ai, difficilement, essayé d'écouter cet improbable sac de noeuds. Passons sur "la boite à cons" dont le terme me semble particulièrement mal choisi (c'est un "coach" qui a inventé ce nom ?). Je retiendrai cette phrase qui m'a choqué&amp;nbsp;: "les managers deviennent des story tellers". Impossible pour moi d'imaginer un voyage vers l'agilité via des techniques à la frontière de la manipulation mentale. Bref, nous n'avons pas les mêmes valeurs.&lt;/li&gt;
&lt;li&gt;L'impression de grand fossé entre le monde des communicants et des organisants d'un côté et les codeurs de l'autre. Ce sentiment n'a rien de nouveau mais certains éléments anodins ne font rien pour arranger les choses. Je pense par exemple aux "personas" censées guider les gens vers les sessions faites pour les gens comme eux. Je pense à la 2ème keynote (oui, toujours la même) où est évoquée la classification des cultures d'un Michael Sahota qui, à mon avis, se trompe lourdement sur le &lt;a href="http://thecleancoder.blogspot.fr/2011/01/brining-balance-to-force.html"&gt;Software Craftsmanship&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Les questions (que je me suis) posées&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Que vaut la règle 5 ("One dot per line") des Object Calisthenics&amp;nbsp;? Surtout si l'on considère les DSL internes.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/LudoMeurillon/status/266525612791980032"&gt;Est-ce qu'on est forcément con quand on est sceptique ou quand on résiste a un changement ?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/BodySplash/status/266527663064240129"&gt;Combien de développeurs continuent à souffrir sur du code de merde ?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Suite aux approches impératives et fonctionnelles du jeu de la vie vues dans le hands on Clojure, le langage C# n'est-il pas actuellement plus fonctionnel qu'impératif&amp;nbsp;?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Les lecons (re-)apprises&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/oaz/status/266459554194284544"&gt;Le nombre de bugs n'est pas une mesure de la qualité&lt;/a&gt;&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/11/10/#pnote-459-1" id="rev-pnote-459-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/BodySplash/status/266477783709003776"&gt;Pour s'améliorer il faut s'entraîner&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/guillaume_agile/status/266521088417206272"&gt;Hors du rock point de culture...&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Remerciements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Au staff en rouge pour son implication tout au long de la journée. Je garderai cette image d'une salle de conf transformée quelques minutes en atelier pour le Clojure hands on.&lt;/li&gt;
&lt;li&gt;Aux personnes rencontrées et avec qui j'ai pu discuter. Impossible de toutes les citer sans en oublier mais je remercie ici &lt;a href="http://www.arpinum.fr/equipe/"&gt;Michael, Charles et Jean-Baptiste&lt;/a&gt; sans qui je n'aurais pas autant apprécié mon séjour.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Ils en parlent aussi&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://xnopre.blogspot.fr/2012/11/agile-grenoble-et-agile-innovation-2012.html"&gt;Xavier Nopre&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://agilarium.blogspot.fr/2012/11/retrospective-de-lagile-grenoble-2012.html"&gt;Fabrice Aimetti&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://atelierlogiciel.wordpress.com/2012/11/11/agile-grenoble-2012-cultiver-le-desir-et-le-plaisir-des-utilisateurs-et-des-collaborateurs/"&gt;Alfred Almendra&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.agilex.fr/2012/11/agile-grenoble-2012/"&gt;Alexandre Boutin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ayeba.fr/2012/11/agile-grenoble-2012/"&gt;Alexis Monville&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://agileinthemix.com/fr/2012/11/agile-grenoble-2012-retrospective/"&gt;Mathieu Cans&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Pour aller plus loin&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/alexis/the-agilists"&gt;Les slides de "The agilists, duo de retour d'expérience sauce aigre douce"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/cney/outils-informatiques-agiles-au-sein-dune-agence-digitale"&gt;Les slides de "Outils informatiques agiles au sein d'une agence digitale"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/martinsson/AgileGrenoble2012"&gt;Le code de "Changer pour mieux coder"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.slideshare.net/ncapponi/un-code-maintenable-avec-le-principe-de-responsabilite-unique"&gt;Les slides de "Well-crafted software: un code maintenable avec le principe de responsabilité unique"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://prezi.com/myzuvtkmi0in/po-tirez-toute-la-puissance-de-lagilite/"&gt;Les slides de "Product Owner&amp;nbsp;: comment tirer toute la puissance de l'agilité"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://prezi.com/4uw2xeukk5pu/tdd-du-mythe-a-la-realite/"&gt;Les slides de "Mise en place du TDD: du mythe à la réalité"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.slideshare.net/thierrycros/quel-chemin-vers-lagilit"&gt;Les slides de "Quel chemin vers l'agilité ?"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/calton13/agile-tour-toulouse-2012-il-tait-une-fois-la-vie-dun-product-owner"&gt;Les slides de "Il était une fois la vie d’un Product Owner"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/FabriceChaminand/agile-grenoble-2012"&gt;Les slides de "Qualité: Stop à la procrastination"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.google.com/presentation/pub?id=1InXjY2bCyZvMLG0aVzxEDwdKZhyvz6XmaPoqR-Ka3aU&amp;amp;start=false&amp;amp;loop=false&amp;amp;delayms=3000"&gt;Les slides de "Des mots, des maux&amp;nbsp;? Démo !"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.slideshare.net/VincentDaviet/collaborer-et-si-on-improvisait"&gt;Les slides de "Collaborer, et si on improvisait ?"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.slideshare.net/ncapponi/dev-opskelkoov17-slideshare"&gt;Les slides de "DevOps@Kelkoo"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/jfjago/agilit-pour-les-nuls"&gt;Les slides de "L'agilité pour les nuls"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.slideshare.net/xnopre/ingnierie-agile-noubliez-pas-vos-dveloppeurs-15090468"&gt;Les slides de "Ingénierie agile, outils et bonnes pratiques&amp;nbsp;: n'oubliez pas vos développeurs !"&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/11/10/#rev-pnote-459-1" id="pnote-459-1"&gt;1&lt;/a&gt;] Bug ou pas bug, la valeur que retire l'utilisateur du produit est une mesure de la qualité&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/11/10/Agile-Grenoble-2012%2C-ma-journ%C3%A9e-chez-les-bin%C3%B4mes#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/11/10/Agile-Grenoble-2012%2C-ma-journ%C3%A9e-chez-les-bin%C3%B4mes#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/459</wfw:commentRss>
      </item>
    
  <item>
    <title>Agile Tour Toulouse 2012, entre câlinothérapie et WTFs</title>
    <link>http://agilitateur.azeau.com/post/2012/10/28/Agile-Tour-Toulouse-2012%2C-entre-c%C3%A2linoth%C3%A9rapie-et-WTFs</link>
    <guid isPermaLink="false">urn:md5:50caa87de59c1a9cd4afc9344c4a9281</guid>
    <pubDate>Sun, 28 Oct 2012 18:49:00 +0100</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
            
    <description>    &lt;p&gt;&lt;a href="http://www.allocine.fr/series/ficheserie-4996/photos/detail/?cmediafile=19775179"&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/.19775179.jpg-r_760_x-f_jpg-q_x-xxyxx_s.jpg" alt="Pays des Bisounours" style="float:right; margin: 0 0 1em 1em;" title="Pays des Bisounours" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Voici mon compte-rendu avec, parce que c'est Toulouse, un petit côté "rétrospective de l'organisation"&lt;/p&gt;


&lt;h3&gt;Ce qui était bien&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La session plénière de début de journée. La &lt;a href="http://att2012.herokuapp.com/events/41"&gt;pièce de théatre&lt;/a&gt; de &lt;a href="http://thierrycros.net/"&gt;Thierry&lt;/a&gt; et &lt;a href="http://www.davidbrocard.org/"&gt;David&lt;/a&gt; fut un vrai régal. Quelqu'un a fait une video&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Le bon accueil fait à &lt;a href="http://att2012.herokuapp.com/events/88"&gt;ma présentation&lt;/a&gt;. J'étais un peu inquiet pour cette première de "Deux ans dans le flux" et le fait que je connaisse un nombre important de personnes dans l'assistance n'a rien fait pour arranger les choses. Je tiens particulièrement à remercier &lt;a href="http://att2012.agiletoulouse.fr/speakers/92"&gt;Géry Derbier&lt;/a&gt; pour la discussion qui a suivi&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/10/28/#pnote-458-1" id="rev-pnote-458-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;La compagnie de quelques sympathiques bordelais le temps du repas de midi (à noter que la fluidité dans la distribution des paniers repas n'avait rien de comparable avec la lenteur du buffet de l'an passé)&lt;/li&gt;
&lt;li&gt;La &lt;a href="http://att2012.herokuapp.com/events/96"&gt;"1ère année de Transition Agile à Air France"&lt;/a&gt;. C'est le genre de présentation "l'agilité vue d'en haut" où l'on n'apprend pas grand chose pour son usage quotidien (à moins d'être un DSI ?) mais qui fait toujours plaisir à voir.&lt;/li&gt;
&lt;li&gt;La session de cloture &lt;a href="http://att2012.herokuapp.com/events/89"&gt;"Agile Unlimited"&lt;/a&gt; où Alexandre a bien marqué la différence entre "utiliser des pratiques que l'on rencontre dans l'agilité", ce que tout le monde peut faire facilement et "être agile", qui nécessite un changement culturel.&lt;/li&gt;
&lt;li&gt;Les discussions qui ont continué pendant la soirée...&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Ce qui était moins bien&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;L'adéquation des sessions aux salles en fonction de leur taille. Vu le nombre de personnes restant debout, j'ai préféré laisser ma place pour &lt;a href="http://att2012.herokuapp.com/events/95"&gt;"Clean Code"&lt;/a&gt;&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/10/28/#pnote-458-2" id="rev-pnote-458-2"&gt;2&lt;/a&gt;]&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://att2012.herokuapp.com/events/87"&gt;"L'agilité dans le référentiel Airbus"&lt;/a&gt;. Globalement nul. J'aurais besoin d'un billet à part entière pour expliquer en détail le problème. Il faudrait que le comité de sélection soit plus vigilant à l'avenir.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://att2012.herokuapp.com/events/86"&gt;"L'agilité&amp;nbsp;: innovation utile au business !"&lt;/a&gt;. Session inutile. Un contenu formellement juste mais loin de ce que pouvait laisser penser le titre. Ca ressemblait plutôt à une introduction à Scrum. J'ai l'impression que l'intervenant s'est contenté de recycler les slides qui lui servent pour présenter l'agilité à ses clients. J'ai quitté la salle en cours de route.&lt;/li&gt;
&lt;li&gt;La &lt;em&gt;non-sélection&lt;/em&gt; des sessions. 22 conférences retenues sans critères très pertinents (les ateliers sont un cas à part qui ne pose pas de problème)&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/10/28/#pnote-458-3" id="rev-pnote-458-3"&gt;3&lt;/a&gt;]&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Les questions (que je me suis) posées&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Est-ce que je vis dans le pays de bisounours&amp;nbsp;? (comme me l'ont dit plusieurs auditeurs de ma présentation)&lt;/li&gt;
&lt;li&gt;Si je vis vraiment dans le pays de bisounours, pourquoi les autres semblent-ils insatisfaits de l'endroit où ils vivent mais se contentent de chercher une méthode qui leur permette de faire avec&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Pourquoi les gens disent "méthodologie" à la place de "méthode"&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Le nombre de WTFs sur twitter est-il une bonne métrique de la qualité d'une présentation&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Ne faudrait-il pas supprimer une ou deux salles de conférence&amp;nbsp;? 4 conférences en parallèle, c'est définitivement trop.&lt;/li&gt;
&lt;li&gt;Ne faudrait-il pas mieux utiliser le grand amphi en sélectionnant et y programmant des sessions qui sortent du lot&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Ne faudrait-il pas rajouter une 3ème piste d'ateliers&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Ne faudrait-il pas dédier une salle aux "open talks" et, par exemple, initier le contenu quelques semaines avant, du genre "la salle dont vous faites le programme"&amp;nbsp;?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Les lecons (re-)apprises&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La doc ça risque pas de planter ou de marcher&lt;/li&gt;
&lt;li&gt;Si on veut être agile, on ne peut pas mettre la qualité de côté&lt;/li&gt;
&lt;li&gt;Si on utilise le mot agile c'est que l'on est prêt à changer de culture&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Remerciements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Merci à tous ceux qui ont rendu cette journée possible&lt;/li&gt;
&lt;li&gt;Une mention spéciale aux étudiants de l'université Paul Sabatier qui se sont auto-organisés pour assurer l'accueil, la permanence et le time-tracking tout au long de la journée&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Ils en parlent aussi&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://prezi.com/9gvh20hbmwy0/agile-tour-toulouse-2012/"&gt;Enguerran Colson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.genigraph.fr/2012/11/01/agile-tour-toulouse-2012/"&gt;Vincent Ferries&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.agilex.fr/2012/11/agile-tour-toulouse/"&gt;Alexandre Boutin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.aubryconseil.com/post/477"&gt;Claude Aubry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Pour aller plus loin&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/ekito-fr/lean-startup-ekito-agile-tour-toulouse-2012"&gt;Les slides de "Expérimentation Lean Startup"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://prezi.com/gd2duot6-wtv/premiere-annee-de-transition-agile-a-air-france/"&gt;Les slides de "Première année de transition agile à Air France"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/jeromeavoustin/clean-code-en-pratique-14732075"&gt;Les slides de "Clean Code"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/calton13/agile-tour-toulouse-2012-il-tait-une-fois-la-vie-dun-product-owner"&gt;Les slides de "Il était une fois dans la vie d'un product owner"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/christopheheral/tfs-2012-un-pas-vers-lagilit-en-avant-ou-en-arrire-14921788"&gt;Les slides de "TFS 2012&amp;nbsp;: un pas vers l'agilité... en avant ou en arrière ?"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://thierrycros.net/public/docs/AgileTourToulouse2012-QuelCheminVerslAgilite.pdf"&gt;Les slides de "Quel chemin vers l'agilité ?"&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/mimmozzo_/the-testing-strategy"&gt;Les slides de "The Testing Strategy"&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/10/28/#rev-pnote-458-1" id="pnote-458-1"&gt;1&lt;/a&gt;] et je viens de commander &lt;a href="http://www.amazon.fr/gp/product/0201699699/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=lagilit-21&amp;amp;linkCode=as2&amp;amp;camp=1642&amp;amp;creative=19458&amp;amp;creativeASIN=0201699699"&gt;Agile Software Development&lt;/a&gt; d'Alistair Cockburn&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/10/28/#rev-pnote-458-2" id="pnote-458-2"&gt;2&lt;/a&gt;] Après Bordeaux et Toulouse, il ne me reste que Montpellier pour (enfin) voir Jérôme&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/10/28/#rev-pnote-458-3" id="pnote-458-3"&gt;3&lt;/a&gt;] NB : je fait partie des personnes qui ont "sélectionné"&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/10/28/Agile-Tour-Toulouse-2012%2C-entre-c%C3%A2linoth%C3%A9rapie-et-WTFs#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/10/28/Agile-Tour-Toulouse-2012%2C-entre-c%C3%A2linoth%C3%A9rapie-et-WTFs#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/458</wfw:commentRss>
      </item>
    
  <item>
    <title>Engagez-vous ils disaient...</title>
    <link>http://agilitateur.azeau.com/post/2012/10/15/Engagez-vous-ils-disaient...</link>
    <guid isPermaLink="false">urn:md5:b90a2d1e7e9b0c087b8107b1e13ca0be</guid>
    <pubDate>Mon, 15 Oct 2012 13:55:00 +0200</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
            
    <description>    &lt;p&gt;&lt;a href="http://commons.wikimedia.org/wiki/File%3AChabal_Rugby_Racing_vs_Stade_Toulousain_311009.jpg"&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/320px-Chabal_Rugby_Racing_vs_Stade_Toulousain_311009.jpg" alt="Chabal Rugby Racing vs Stade Toulousain 311009" style="float:right; margin: 0 0 1em 1em;" title="By http://www.flickr.com/photos/tfa/ Thomas Faivre-Duboz (http://www.flickr.com/photos/tfa/4075077486/) CC-BY-SA-2.0 (http://creativecommons.org/licenses/by-sa/2.0), via Wikimedia Commons" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;Air du temps ou coïncidence, je suis tombé sur deux billets traitant de l'engagement des développeurs&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;Tout d'abord, dans le &lt;em&gt;Bouzin Agile&lt;/em&gt;&amp;nbsp;: &lt;a href="http://www.bouzin-agile.fr/?post/2012/10/06/Developpeurs-mettez-vos-couilles-sur-le-billot"&gt;Développeurs mettez vos couilles sur le billot&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;L'engagement est la liste des Users Stories que l'équipe pense développer durant l'itération. [...] l'engagement permet quelque chose de très important à mes yeux&amp;nbsp;: de placer la barre à une certaine hauteur et de comparer à la fin de l'itération ce qui a été réalisé&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;Et le jour suivant chez &lt;em&gt;Coacher une équipe agile&lt;/em&gt;&amp;nbsp;: &lt;a href="http://vmessager.tumblr.com/post/33366039842/extrait-6-obtenir-lengagement-de-lequipe"&gt;Obtenir l’engagement de l’équipe&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;on sait combien dans une démarche agile, la notion d’engagement sur le résultat du sprint est un élément-clé [...] Comment obtenez-vous l’engagement de tous les coéquipiers sur le nombre de story points ou le nombre de user stories, bref, sur le périmètre défini&amp;nbsp;?&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;J'ai un peu de mal à partager ces points de vue.&lt;/p&gt;


&lt;h3&gt;«&amp;nbsp;L'engagement, c'est un mur conçu expressément pour que l'on fonce dedans.&amp;nbsp;»&lt;/h3&gt;


&lt;p&gt;A vrai dire, je ne me suis jamais vraiment préoccupé de cette notion d'engagement. L'équipe dans laquelle je travaille a toujours plus ou moins eu un certain sens du travail à accomplir et des attentes de nos utilisateurs.&lt;br /&gt;
C'était vrai jusqu'à l'automne 2010 où une release s'est relativement mal passée. L'engagement était au coeur du malaise. Les développeurs, implicitement &lt;em&gt;engagés&lt;/em&gt;, ont tenté vainement de livrer tout ce qui avait été, à leurs yeux, "promis", quitte à prendre quelques libertés avec les bonnes pratiques.&lt;br /&gt;
&lt;br /&gt;
Alors on pourra toujours argumenter que l'équipe n'était pas prête à assumer cet engagement, qu'elle n'avait pas la maturité nécessaire pour concilier travail bien fait et engagement sur un périmètre. On pourra trouver toutes les raisons du monde pour dire que l'engagement c'est bien mais que, &lt;em&gt;évidemment&lt;/em&gt;, il faut &lt;strong&gt;&amp;lt;insérer ici votre pratique favorite qu'il ne faut jamais abandonner&amp;gt;&lt;/strong&gt;.&lt;br /&gt;
Tout ça pour quoi ?&lt;br /&gt;
Quel bénéfice réel tire-t-on d'une promesse sur un contenu sachant qu'il y a des pratiques plus prioritaires et non négociables ?&lt;br /&gt;
&lt;br /&gt;
Pour ma part, je ne vois qu'un seul "avantage"&amp;nbsp;: la possibilité de blâmer ceux qui n'ont pas tenu leur promesse.&lt;br /&gt;
Si on considère &lt;a href="http://agilitateur.azeau.com/post/2006/11/03/Black-box-project-management"&gt;les trois variables coût-délai-contenu&lt;/a&gt;, on sait que lorsque deux d'entre elles sont fixées, la troisième ne peut qu'être mesurée ou espérée. Or, définir un engagement, c'est vouloir fixer, par des moyens détournés et avec une certaine bassesse, la variable &lt;em&gt;contenu&lt;/em&gt; quand le &lt;em&gt;coût&lt;/em&gt; et le &lt;em&gt;délai&lt;/em&gt; sont déjà fixés.&lt;/p&gt;


&lt;p&gt;Même l'argument "mais c'est pour le bien de l'équipe pour qu'elle réfléchisse à la façon de faire &lt;em&gt;mieux&lt;/em&gt;" ne tient pas&amp;nbsp;: soit on fait confiance aux gens pour qu'ils donnent le meilleur d'eux mêmes, soit on ne fait pas confiance.&lt;/p&gt;


&lt;h3&gt;«&amp;nbsp;Le sage trouve mieux son compte à ne point s'engager qu'à vaincre.&amp;nbsp;»&lt;/h3&gt;


&lt;p&gt;La petite mésaventure que je mentionnais un peu plus haut m'aura au moins permis de faire avancer une approche différente &lt;a href="http://agilitateur.azeau.com/post/2011/04/05/Bye-Bye-Scrum"&gt;en me donnant l'occasion de supprimer les itérations&lt;/a&gt; pour aller vers un développement plus &lt;em&gt;fluide&lt;/em&gt;.&lt;br /&gt;
Finies les itérations, finies les durées fixes, finis les engagements sur un contenu d'itération. L'équipe se focalise sur les deux ou trois éléments de backlog produit actifs à un instant donné et si un engagement lui est demandé, c'est de faire chaque jour de son mieux pour que ces éléments soient réalisés.&lt;br /&gt;
&lt;br /&gt;
Mais, alors, me direz-vous, si l'équipe ne s'engage plus comment pourrais-je &lt;del&gt;leur mettre la pression à cette bande de bons à rien&lt;/del&gt; savoir à quelle date telle ou telle fonctionnalité sera livrée au client ?&lt;br /&gt;
La planification, c'est à dire le fait de prédire quels élements seront réalisés ou pas pour une date donnée ne devrait pas être demandé aux développeurs. D'ailleurs, cela ne devrait être demandé à aucun être humain car aucun d'entre eux n'a les moyens de faire cette prédiction.&lt;br /&gt;
Chez nous, on a adopté une technique où on laisse une machine nous donner des probabilités de livraison en fonction des temps de réalisation observés sur les éléments passés&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/10/15/#pnote-457-1" id="rev-pnote-457-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;. A l'usage, les prévisions que nous obtenons sont correctes (et même meilleures qu'en faisant intervenir des humains) tout en ayant fait baisser la pression inutile qui pèse sur les épaules d'une équipe que l'on pousserait trop à s'engager.&lt;br /&gt;
&lt;br /&gt;
Ceux qui voudraient avoir un peu plus de détails sur ce qui a changé dans notre équipe du fait de cette transition méthodologique, je leur propose de venir le jeudi 25 octobre à Agile Tour Toulouse pour &lt;a href="http://att2012.agiletoulouse.fr/events/88"&gt;"Deux ans dans le flux"&lt;/a&gt;...&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/10/15/#rev-pnote-457-1" id="pnote-457-1"&gt;1&lt;/a&gt;] la description détaillée de cette technique sera le sujet d'un billet ultérieur&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/10/15/Engagez-vous-ils-disaient...#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/10/15/Engagez-vous-ils-disaient...#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/457</wfw:commentRss>
      </item>
    
  <item>
    <title>Agile Tour Bordeaux 2012 : j'y étais</title>
    <link>http://agilitateur.azeau.com/post/2012/10/13/Agile-Tour-Bordeaux-2012-%3A-j-y-%C3%A9tais</link>
    <guid isPermaLink="false">urn:md5:022c9b59cf8e62b1d34779ce793caca0</guid>
    <pubDate>Sat, 13 Oct 2012 21:24:00 +0200</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
            
    <description>    &lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/evenements/atbdx2012_small.png" alt="Toi aussi tu y étais" style="float:right; margin: 0 0 1em 1em;" title="Toi aussi tu y étais" /&gt;&lt;/p&gt;


&lt;p&gt;Voici mon petit compte-rendu en "&lt;a href="http://agilarium.blogspot.fr/"&gt;Agilarium&lt;/a&gt;-style".&lt;/p&gt;


&lt;h3&gt;Ce qui était bien&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La keynote de Samir Hanna. Keynote n'est pas un synonyme pour "session plénière qui ouvre ou clôture". La &lt;a href="http://en.wiktionary.org/wiki/keynote"&gt;keynote&lt;/a&gt;, comme son nom l'indique, c'est ce qui donne le ton pour ce qui va suivre et la courte introduction de la journée mettant en avant des valeurs était, en ce sens, la bienvenue.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;What Testers and Developers Can Learn From Each Other&lt;/em&gt; par &lt;a href="https://twitter.com/DavidEvans66"&gt;David Evans&lt;/a&gt;. Un véritable appel à la réconciliation des développeurs avec le test sous toutes ses formes et un orateur vraiment au dessus du lot.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Tests automatisés, le mythe du ROI&lt;/em&gt; par &lt;a href="https://twitter.com/gmantel"&gt;Gilles Mantel&lt;/a&gt;. Une taxonomie des tests très détaillée (peut-être un peu trop pour mon goût de la concision) mais surtout une modélisation du ROI des tests automatisés sur un principe d'option d'achat qu'il faut avoir vu avant d'émettre le moindre avis sur le sujet.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;La voie du programmeur&lt;/em&gt; par &lt;a href="https://twitter.com/BodySplash"&gt;Jean-Baptiste Dusseaut&lt;/a&gt;. Ma session préférée parce qu'elle aborde plein de thèmes qui me tiennent à coeur sur une question fondamentale&amp;nbsp;: comment devient-on un professionnel du développement logiciel&amp;nbsp;? Elle devrait être imposée dans tous les agile tours de France et d'ailleurs.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Sociocratie: une gouvernance agile&lt;/em&gt; par &lt;a href="https://twitter.com/thierrycros"&gt;Thierry Cros&lt;/a&gt;. J'ai encore du mal à voir comment cette idée disruptive peut prendre de l'ampleur dans le contexte actuel mais comment ne pas faire confiance à quelqu'un qui a senti la lame de fond du mouvement agile dès ses débuts&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;La soirée qui a suivi mais vous ne saurez rien&amp;nbsp;: il fallait être là.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Ce qui était moins bien&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;La densité des sessions de l'après-midi. Quatre sessions en quatre heures, c'est un peu trop. Du coup, j'ai zappé le dernier créneau qui ne manquait pourtant pas d'interêt avec les sessions d'&lt;a href="https://twitter.com/isabelmonville"&gt;Isabel&lt;/a&gt;, &lt;a href="https://twitter.com/JeromeAvoustin"&gt;Jérôme&lt;/a&gt; et &lt;a href="https://twitter.com/jonathan_scher"&gt;Jonathan&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;"Utilisateur mon amour ma migraine" par &lt;a href="https://twitter.com/wickedgeekie"&gt;Sophie Freiermuth&lt;/a&gt;. De mon point de vue, la session fut à côté de la plaque sur l'aspect méthodes agiles. Des notions mal utilisées&amp;nbsp;: quand on retravaille un existant, on fait de l'incrémental, pas de l'itératif&amp;nbsp;; une user story n'est jamais une spec détaillée, c'est au plus une invitation a discuter... Les plus gros travers restent cependant le BDUF omniprésent (le développeur est content quand on lui apporte une spec hyper détaillée et qu'il n'a pas à se poser trop de questions sur ce qu'il doit coder), la communication érigée en non-valeur ("le designer n'est pas intéresse par le code" - et donc il n'a aucune raison d'aller s'asseoir à côté du développeur) et l'hyper-spécialisation ("un développeur c'est quelqu'un qui résout des problèmes techniques" - qu'il ne se mêle pas de choses qui le dépassent !) Je suis pourtant convaincu qu'il y a une marge de progression énorme en User eXperience pour la plupart des produits logiciels mais il faut une approche qui colle avec un développement logiciel professionnel. A noter&amp;nbsp;: je n'ai pas encore vu &lt;a href="http://www.youtube.com/watch?v=ta6PLKPF7oU"&gt;cette session de Sophie Freiermuth&lt;/a&gt; à Mix-IT qui, parait-il, était très bien.&lt;/li&gt;
&lt;li&gt;Comme dans toutes les conférences de ce genre, il est impossible de voir toutes les sessions et j'ai donc surement raté des trucs intéressants.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Les questions (que je me suis) posées&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tests UX, tests exploratoires, tests de sérendipité ne sont-ils pas tous assimilables à des explorations au sens où même si on a une idée en tête, on ne sait pas vraiment où on va&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Peut-on écréter la pyramide des tests de Mike Cohn&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Y a-t-il des maîtres de l'artisanat logiciel et où sont-ils&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Qui sera le premier à écrire un recueil de citations de Kent Beck&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Peut-on être expert en développement logiciel à la sortie d'une école&amp;nbsp;? (nan j'déconne)&lt;/li&gt;
&lt;li&gt;Les loldogs existent-ils&amp;nbsp;? (la réponse est &lt;a href="https://www.google.com/search?q=loldog&amp;amp;tbm=isch"&gt;oui&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Les lecons (re-)apprises&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Une présentation devrait toujours commencer par un gag visuel&lt;/li&gt;
&lt;li&gt;Ce n'est pas en rajoutant des tests que le logiciel devient de meilleure qualité&lt;/li&gt;
&lt;li&gt;L'activité de test n'est jamais terminée, elle n'est qu'arrêtée&lt;/li&gt;
&lt;li&gt;Les testeurs sont nos amis&lt;/li&gt;
&lt;li&gt;Un ami, c'est celui qui aide a démenager un divan&amp;nbsp;; un meilleur ami, c'est celui qui aide a déplacer un corps...&lt;/li&gt;
&lt;li&gt;Mettre en place des tests automatisés, c'est payer une prime limitée pour un gain potentiellement infini&lt;/li&gt;
&lt;li&gt;Il faut nourrir sa passion&lt;/li&gt;
&lt;li&gt;Le coding dojo, c'est comme le fight club&amp;nbsp;: quand on y vient, il faut coder&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/10/13/#pnote-456-1" id="rev-pnote-456-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Pas de commentaires dans le code&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Remerciements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Merci aux organisateurs&amp;nbsp;: &lt;a href="https://twitter.com/bastien_gallay"&gt;Bastien&lt;/a&gt;, &lt;a href="https://twitter.com/florianguerin"&gt;Florian&lt;/a&gt;, &lt;a href="http://agilefeedback.blogspot.fr/"&gt;Samir&lt;/a&gt;, &lt;a href="https://twitter.com/roux_jerome"&gt;Jérôme&lt;/a&gt;, &lt;a href="https://twitter.com/mruellan"&gt;Mickaël&lt;/a&gt; et &lt;a href="https://twitter.com/rolalagile"&gt;Guillaume&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Merci à toutes les personnes qui m'ont dit avoir apprécié ma session. C'était, comme d'habitude pour cet atelier, un peu le bazar par moments mais je pense que tous ceux qui se prennent au jeu en retirent forcément quelque chose - et moi aussi par la même occasion car, malgré le thème et les attentes imposées, c'est à chaque fois différent.&lt;/li&gt;
&lt;li&gt;Et merci à tous les autres sans qui cet évènement n'aurait pas été ce qu'il a été.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Ils en parlent aussi&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://pgrange1.blogspot.fr/2012/10/agile-tour-bordeaux-2012-notes-pour.html"&gt;Pascal Grange&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.arpinum.fr/2012/10/15/agile-tour-bordeaux-2012-la-meilleure-edition/"&gt;Arpinum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ayeba.fr/2012/10/nous-etions-a-lagiletour-bordeaux-2012/"&gt;Ayeba&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://colingarrigasalaun.blogspot.fr/2012/10/agile-tour-bordeaux-2012.html"&gt;Colin Garriga-Salaün&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://thehypertextual.com/2012/10/16/agile-et-hyperlocal-atbdx/"&gt;#hypertextual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bastien.gallay.org/blog/2012/10/17/nous-avons-fait-l-agile-tour-bordeaux-2012-ensemble/"&gt;Bastien Gallay&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://thierrycros.net/?post/2012/10/16/Agile-Tour-Bordeaux-2012-%3A-impressions-de-voyage"&gt;Thierry Cros&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Pour aller plus loin&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/isabelmonville/la-communication-au-service-du-projet"&gt;Les slides d'Isabel Monville&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/jonathanscher/bref-jai-t-product-owner"&gt;Les slides de Jonathan Scher&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/jeromeavoustin/clean-code-en-pratique-14732075"&gt;Les slides de Jérôme Avoustin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://thierrycros.net/?post/2012/10/16/Agile-et-Sociocratie-%3A-bienvenue-en-sociagilit%C3%A9"&gt;Les slides de Thierry Cros&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://prezi.com/eqmsbhlrxjz6/la-voie-du-programmeur-version-longue/"&gt;Les slides de Jean-Baptiste Dusseaut&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/gmantel/atbdx12-agile-testing"&gt;Les slides de Gilles Mantel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fr.slideshare.net/carolilo/agile-tour-bordeaux-octobre-2012-des-mots-des-maux-demo"&gt;Les slides de Caroline Damour-Nobi et Emilie Franchomme&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/10/13/#rev-pnote-456-1" id="pnote-456-1"&gt;1&lt;/a&gt;] dans le vrai fight club, cela n'est vrai que la première fois où l'on y vient - et de toutes façons on ne doit pas en parler&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/10/13/Agile-Tour-Bordeaux-2012-%3A-j-y-%C3%A9tais#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/10/13/Agile-Tour-Bordeaux-2012-%3A-j-y-%C3%A9tais#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/456</wfw:commentRss>
      </item>
    
  <item>
    <title>Agile Tour saison 5</title>
    <link>http://agilitateur.azeau.com/post/2012/09/29/Agile-Tour-saison-5</link>
    <guid isPermaLink="false">urn:md5:948ede7f8eff4dd5eadc78abc5081b4f</guid>
    <pubDate>Sat, 29 Sep 2012 11:27:00 +0200</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
            
    <description>    &lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/evenements/at2012.jpg" alt="at2012.jpg" style="float:right; margin: 0 0 1em 1em;" title="at2012.jpg, sept. 2012" /&gt;L'automne revient et la saison des agile tours recommence. Et cette année, le calendrier "sud-ouest" est plutôt sympathique puisque je vais pouvoir aller à Bordeaux, à Toulouse et à Montpellier dont les étapes sont suffisamment espacées dans le temps&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/09/29/#pnote-453-1" id="rev-pnote-453-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;Le 12 octobre, c'est la 4ème édition de &lt;a href="http://agiletourbordeaux.okiwi.org"&gt;l'agile tour Bordeaux&lt;/a&gt;. Il y a &lt;a href="http://agiletourbordeaux.okiwi.org/pourquoivenir.html"&gt;7 bonnes raison d'y aller&lt;/a&gt; et en plus c'est GRATUIT (mais &lt;a href="http://www.yuticket.com/association-okiwi/ca5f3eb4-6f52-4d8e-818b-ef8847dafb3a-agile-tour-bordeaux-2012.html"&gt;il faut s'inscrire&lt;/a&gt;).&lt;br /&gt;
Il y a même une 8ème raison&amp;nbsp;: j'animerai une session "Si t'es pas SOLID, t'es pas agile", une sympathique expérience de programmation collective avec des composants logiciels humains qui montent sur scène pour découvrir ou re-découvrir le principe de substitution de Liskov, le principe d'inversion de dépendances et autres joyeusetés de la conception logicielle.&lt;br /&gt;
La session est la même que celle présentée à l'agile tour Toulouse l'an dernier, mais &lt;ins&gt;en mieux&lt;/ins&gt; car elle a eu le temps d'être retravaillée et de mûrir.&lt;/p&gt;


&lt;p&gt;Le 25 octobre, c'est la 5ème édition de &lt;a href="http://tour.agiletoulouse.fr/"&gt;l'agile tour Toulouse&lt;/a&gt;. &lt;a href="http://agiletoulouse.fr/boutique/catalog/product_info.php?products_id=37&amp;amp;osCsid=efa97208862788f9e232f8ff48d8fef2"&gt;Il faut toujours s'inscrire&lt;/a&gt;. Celui-là est payant mais le repas est inclus dans le prix.&lt;br /&gt;
J'y présenterai un retour d'expérience&amp;nbsp;: &lt;a href="http://att2012.agiletoulouse.fr/events/88"&gt;Deux ans dans le flux&lt;/a&gt;. J'essaierai de raconter comment, &lt;a href="http://agilitateur.azeau.com/post/2011/04/05/Bye-Bye-Scrum"&gt;depuis l'automne 2010&lt;/a&gt;, notre équipe a gagné en expérience et a modifié son approche du développement logiciel en s'aventurant sur des terrains qui peuvent sembler, a priori, éloignés des méthodes agiles.&lt;br /&gt;
Les orthodoxes de Scrum qui souhaiteraient assister à la session sont priés de laisser leurs oeillères au vestiaire.&lt;/p&gt;


&lt;p&gt;Le 29 novembre, c'est la 2ème édition de &lt;a href="http://at2012.agiletour.org/fr/Montpellier.html"&gt;l'agile tour Montpellier&lt;/a&gt;. Je ne sais pas s'il faut s'inscrire (pas trouvé l'info...) et je ne sais pas si j'y participerai en tant qu'orateur car le programme n'est pas encore connu (j'ai proposé les 2 sessions qui seront à Bordeaux et à Toulouse).&lt;/p&gt;


&lt;p&gt;J'ai parcouru &lt;a href="http://agiletourbordeaux.okiwi.org/programme.html"&gt;le programme de Bordeaux&lt;/a&gt; et &lt;a href="http://att2012.agiletoulouse.fr/events/"&gt;celui de Toulouse&lt;/a&gt;.&lt;br /&gt;
Il y a quelques sessions que je ne veux pas manquer. &lt;a href="https://twitter.com/BodySplash"&gt;Jean-Baptiste&lt;/a&gt; parlera de &lt;a href="http://agiletourbordeaux.okiwi.org/programme.html#LaVoieDuProgrammeur"&gt;la voie du programmeur&lt;/a&gt;,un sujet &lt;a href="http://agilitateur.azeau.com/post/2011/08/25/Agile-Tour-Toulouse-2011-%3A-une-journ%C3%A9e-pour-les-d%C3%A9veloppeurs"&gt;que j'avais eu l'occasion d'approcher&lt;/a&gt; et qui est trop souvent marginalisé dans des conférences &lt;del&gt;scrum&lt;/del&gt; agile. Il y a aussi &lt;a href="https://twitter.com/JeromeAvoustin"&gt;Jérome&lt;/a&gt; avec &lt;a href="http://att2012.agiletoulouse.fr/events/95"&gt;Clean Code&lt;/a&gt;, un sujet technique primordial parmi la foule des sessions "TDD/BDD" ou "intégration continue".&lt;br /&gt;
Je crois aussi que, si l'occasion se présente, je me laisserai tenter par quelques sessions à la frontière des thèmes classiques de l'agilité. Je pense par exemple à &lt;a href="http://agiletourbordeaux.okiwi.org/programme.html#UtilisateurMonAmourMaMigraine"&gt;"Utilisateur, mon amour, ma migraine"&lt;/a&gt;.&lt;br /&gt;
En fonction de l'humeur du moment, il se pourrait aussi que j'aille jouer au troll dans une ou deux sessions (toulousaines) qui me semblent flirter avec l'arnaquagile...&lt;/p&gt;


&lt;p&gt;Bref, de belles journées en perspective&amp;nbsp;!&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/09/29/#rev-pnote-453-1" id="pnote-453-1"&gt;1&lt;/a&gt;] il y a aussi une étape à Pau, voire à Marseille et Nice si on étend aux villes de &lt;a href="http://www.agile-occitanie.org/"&gt;agile Occitanie&lt;/a&gt; - dont Clermont-Ferrand ne fait étrangement pas partie&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/09/29/Agile-Tour-saison-5#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/09/29/Agile-Tour-saison-5#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/453</wfw:commentRss>
      </item>
    
  <item>
    <title>S'il y a un product owner, il peut y avoir un design owner</title>
    <link>http://agilitateur.azeau.com/post/2012/09/28/S-il-y-a-un-product-owner%2C-il-peut-y-avoir-un-design-owner</link>
    <guid isPermaLink="false">urn:md5:4976b3f745af44fd3769de624c4b0ed0</guid>
    <pubDate>Fri, 28 Sep 2012 12:35:00 +0200</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
            
    <description>    &lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/.320px-Dictator_charlie3_s.jpg" alt="Dictator" style="float:right; margin: 0 0 1em 1em;" title="Dictator, sept. 2012" /&gt;Scrum, la méthode agile &lt;a href="http://www.amazon.fr/gp/product/2100563203/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;amp;tag=lagilit-21&amp;amp;linkCode=as2&amp;amp;camp=1642&amp;amp;creative=6746&amp;amp;creativeASIN=2100563203"&gt;la plus populaire&lt;/a&gt;, définit un rôle de &lt;em&gt;product owner&lt;/em&gt;. C'est un membre à part entière de l'équipe de développement qui a certaines responsabilités. Citons principalement&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;décrire les éléments du backlog produit&lt;/li&gt;
&lt;li&gt;les prioriser&lt;/li&gt;
&lt;li&gt;approuver leur implémentation dans le produit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;De manière anti-symétrique, la plupart des autres équipiers (oublions le scrummaster qui ne prend pas part &lt;em&gt;directement&lt;/em&gt; à la création du produit), n'ont pas de rôle exclusif&amp;nbsp;: ils sont pluridisciplinaires.&lt;/p&gt;


&lt;p&gt;Il y a une possibilité pour régler ce problème de symétrie, c'est de &lt;a href="http://addinquy.tumblr.com/post/30440618994/en-finir-avec-le-product-owner"&gt;dissoudre la responsabilité PO au sein de l'équipe&lt;/a&gt; en rendant chaque membre responsable des objectifs business et non plus seulement de la construction du produit. Les multiples approches du genre "PO proxy" ne sont, je pense, que des manières plus ou moins heureuses de tendre vers une telle organisation.&lt;/p&gt;


&lt;p&gt;Il y a toutefois une autre façon pour redonner un peu de symétrie&amp;nbsp;: tout comme il y a un product owner qui agit en tant que leader sur l'objectif business, il pourrait y avoir un &lt;em&gt;design owner&lt;/em&gt; qui assurerait le leadership sur la conception du produit.&lt;br /&gt;
J'ai le sentiment (peut-être à tord ?) qu'une telle approche n'aurait pas bonne presse dans un contexte qui se définit comme &lt;em&gt;agile&lt;/em&gt;.&lt;br /&gt;
En supprimant le command &amp;amp; control matérialisé la plupart du temps par un chef de projet omnipotent qui est avant tout un &lt;em&gt;chef du planning et des ressources&lt;/em&gt;, la mouvance agile en est arrivée à promouvoir des organisations sans aucun &lt;em&gt;chef&lt;/em&gt;.&lt;br /&gt;
J'ai l'impression (toujours peut-être à tord ?) qu'aujourd'hui il est difficile de faire valoir que certaines responsabilités de conception puissent être assignées à quelqu'un en particulier dont le choix serait prépondérant, tout comme le choix de priorisation d'un product owner est prépondérant sur celui des autres personnes qui peuvent concourir à l'objectif business.&lt;/p&gt;


&lt;p&gt;Sans aller jusqu'à faire la promotion d'organisation de développement logiciel assez autocratiques comme pouvait le suggérer Brooks avec son &lt;a href="http://fr.wikipedia.org/wiki/Le_Mythique_homme-mois#Le_.C2.AB_chirurgien_en_chef_.C2.BB"&gt;chirurgien en chef&lt;/a&gt; dans le contexte des années 70, il me semble qu'une organisation peut introduire des rôles de leadership de conception tout en restant en accord avec les valeurs et les principes du manifeste agile.&lt;/p&gt;


&lt;p&gt;&lt;em&gt;Les utilisateurs ou leurs représentants et les développeurs doivent travailler ensemble quotidiennement tout au long du projet.&lt;/em&gt;&lt;br /&gt;
&lt;em&gt;Les meilleures architectures, spécifications et conceptions émergent d'équipes autoorganisées.&lt;/em&gt;&lt;br /&gt;
Si cela est vrai en attribuant un rôle spécial à un unique product owner, alors cela reste vrai en attribuant un rôle spécial à un unique design owner.&lt;br /&gt;
Il ne s'agit pas de déposséder l'équipe de sa capacité d'autoorganisation. Tout équipier peut avoir son mot à dire sur tout ce qui concerne le produit. Un design owner dont les choix seraient contestés par la majorité des équipiers aurait un futur assez compromis. Cela n'est d'ailleurs pas moins vrai pour un product owner qui ferait des choix de priorités plus que douteux.&lt;/p&gt;


&lt;p&gt;Le terme &lt;em&gt;owner&lt;/em&gt; est d'ailleurs probablement mal choisi autant pour l'un que pour l'autre. Il s'agit plus de &lt;em&gt;leaders&lt;/em&gt; qui donnent le cap et, par leur capacité à porter des décisions, assurent une certaine cohérence à l'ensemble.&lt;br /&gt;
Le fait est que dans la réalité des développements logiciels, ce rôle de design leader existe quasi-systématiquement de manière explicite ou implicite. Il existait même explicitement dans certaines méthodes agiles aujourd'hui oubliées&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/09/28/#pnote-454-1" id="rev-pnote-454-1"&gt;1&lt;/a&gt;]&lt;/sup&gt; à cause de la déferlante scrum.&lt;br /&gt;
Le monde de l'open source fourmille de &lt;em&gt;dictateurs bienveillants&lt;/em&gt; qui sont un point positif pour la bonne marche de nombreux projets.&lt;br /&gt;
Plus généralement dans le monde de l'entreprise, qu'on le nomme &lt;a href="http://en.wikipedia.org/wiki/Lead_programmer"&gt;Lead Programmer&lt;/a&gt; ou Tech Lead, ce responsable de la conception fait plutôt du bien à un projet de développement logiciel, du moins pour ce que j'ai pu en voir.&lt;/p&gt;


&lt;p&gt;Son absence inconstestable dans la terminologie agile actuelle est pour moi un mystère.&lt;br /&gt;
Dans &lt;a href="http://www.amazon.fr/gp/product/0201733862/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&amp;amp;tag=lagilit-21&amp;amp;linkCode=as2&amp;amp;camp=1642&amp;amp;creative=6746&amp;amp;creativeASIN=0201733862"&gt;Software Craftsmanship: The New Imperative&lt;/a&gt;, Pete Mc Breen abordait l'organisation d'un projet de développement logiciel en parlant de &lt;em&gt;Lead Software Craftsman&lt;/em&gt;. Le mouvement actuel du même nom (software craftsmanship), émanation de la mouvance agile, a repris bien des idées déjà présentes chez Mc Breen il y a 12 ans mais l'organisation avec hiérarchisation de rôles n'en fait étrangement pas partie.&lt;/p&gt;


&lt;p&gt;Les agilistes sont-ils victimes d'un syndrome d'égalitarisme&amp;nbsp;?&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/09/28/#rev-pnote-454-1" id="pnote-454-1"&gt;1&lt;/a&gt;] par exemple le team leader dans DSDM&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/09/28/S-il-y-a-un-product-owner%2C-il-peut-y-avoir-un-design-owner#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/09/28/S-il-y-a-un-product-owner%2C-il-peut-y-avoir-un-design-owner#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/454</wfw:commentRss>
      </item>
    
  <item>
    <title>La fausse bonne idée des Virtual Extension Methods dans Java 8</title>
    <link>http://agilitateur.azeau.com/post/2012/03/20/La-fausse-bonne-id%C3%A9e-des-Virtual-Extension-Methods-dans-Java-8</link>
    <guid isPermaLink="false">urn:md5:fc6ede290ec656f566d710228dfd416d</guid>
    <pubDate>Tue, 20 Mar 2012 08:08:00 +0100</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
        <category>csharp</category><category>java</category>    
    <description>    &lt;p&gt;Quand on s'intéresse aux évolutions de Java, il faut lire &lt;a href="http://www.touilleur-express.fr/"&gt;le Touilleur Express&lt;/a&gt; et plus particulièrement &lt;a href="http://www.touilleur-express.fr/2012/03/16/remi-forax-au-paris-jug/"&gt;son compte rendu "Rémi Forax au Paris JUG"&lt;/a&gt;. Apparemment, les lambda expressions feront leur apparition dans la version 8 du langage, ce dont tout le monde devrait se réjouir.&lt;br /&gt;
Je ne suis pas un habitué de Java. Mon premier langage fut le C++ et aujourd'hui celui que je maîtrise le mieux reste C# mais comment résister à l'envie de jeter un coup d'oeil aux évolutions de Java au moment où celui-ci se met à rattraper (un petit peu&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/20/#pnote-452-1" id="rev-pnote-452-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;) son retard sur C# ?&lt;br /&gt;
Je vais essayer d'expliquer ce que j'ai compris et pourquoi je pense qu'un des choix effectués ne me semble pas être des plus judicieux&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/20/#pnote-452-2" id="rev-pnote-452-2"&gt;2&lt;/a&gt;]&lt;/sup&gt;&lt;/p&gt;


&lt;p&gt;Un des principaux usages des lambdas expressions dans les langages orientés objet, c'est la manipulation de collections à travers quelques méthodes générales (filtrage, projection, aggregats, ...) paramétrées par des lambdas expressions.&lt;br /&gt;
C'est bien évidemment un des objectifs de l'introduction des lambdas dans Java comme l'explique &lt;a href="https://blogs.oracle.com/briangoetz/"&gt;Brian Goetz&lt;/a&gt; dans ces slides de novembre dernier&amp;nbsp;: &lt;a href="http://blogs.oracle.com/briangoetz/resource/devoxx-lang-lib-vm-co-evol.pdf"&gt;http://blogs.oracle.com/briangoetz/resource/devoxx-lang-lib-vm-co-evol.pdf&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;En pratique, le but est de pouvoir écrire le code suivant en Java&amp;nbsp;:&lt;/p&gt;
&lt;pre class="brush: java;"&gt;
List&amp;lt;Student&gt; students = ...
double highestScore =
    students.filter(s -&gt; s.getGradYear() == 2011)
                .map(s -&gt; s.getScore())
                .reduce(0.0, Integer::max);
&lt;/pre&gt;



&lt;p&gt;Cela n'est bien sûr que l'équivalent de ce que l'on peut écrire en C# depuis quelques années déjà&amp;nbsp;:&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;
List&amp;lt;Student&gt; students = ...
double highestScore =
    students.Where(s =&gt; s.GradYear == 2011)
                .Select(s =&gt; s.Score)
                .Aggregate(0.0, Math.Max);
&lt;/pre&gt;



&lt;p&gt;Une question annexe est alors&amp;nbsp;: comment définir les méthodes filter/map/reduce sur une collection ?&lt;br /&gt;
C# a fait un choix simple. Where/Select/Aggregate et bon nombre d'autres opérations sont définies comme &lt;em&gt;méthodes d'extension statiques&lt;/em&gt;. Ce sont tout simplement des méthodes statiques d'une classe statique qu'un artifice du compilateur permet de faire apparaitre comme des méthodes de toute énumération.&lt;br /&gt;
Dans la suite de ce billet je les appelerai SEM (pour Static Extension Method)&lt;/p&gt;


&lt;p&gt;Pour le compilateur C#, le code précédent est strictement équivalent à celui-ci&amp;nbsp;:&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;
double highestScore =
  Enumerable.Aggregate (
    Enumerable.Select (
      Enumerable.Where (students, s =&gt; s.GradYear == 2011),
      s =&gt; s.Score
    ),
    0.0, Math.Max
  );
&lt;/pre&gt;



&lt;p&gt;Visiblement, cette façon de faire ne plait pas aux concepteurs de Java. Brian Goetz détaille les objections suivantes&amp;nbsp;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Classes don’t know about their extension methods so cannot provide a “better” implementation&lt;br /&gt;
Not reflectively discoverable&lt;br /&gt;
No covariant overrides&lt;br /&gt;
Brittle – if default changes, clients have to be recompiled&lt;br /&gt;
Poor interaction with existing instance methods of same name&lt;br /&gt;
Not very object-oriented&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;Voyons un peu ce qu'il en est vraiment.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Les classes ne connaissent pas leurs méthodes d'extension. C'est en partie vrai (seule l'interface IQueryable permet de faire varier l'implémentation des SEM, c'est d'ailleurs le fondement de LINQ) mais dans la plupart des cas, on n'en a rien à faire. Les SEM ne sont pas là pour étendre une abstraction, elles sont là pour proposer un concept d'implémentation indépendant du type auquel elles se rapportent.&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/20/#pnote-452-3" id="rev-pnote-452-3"&gt;3&lt;/a&gt;]&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Etant indépendantes des types, les SEM ne sont pas accessibles à travers la réflexion. C'est vrai mais à quoi cela pourrait servir&amp;nbsp;? Quand on se soucie de réflexion sur les méthodes d'un type, c'est que l'on aurait grand besoin, au choix, de revoir sa conception&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/20/#pnote-452-4" id="rev-pnote-452-4"&gt;4&lt;/a&gt;]&lt;/sup&gt; ou d'aller vers un langage plus dynamique.&lt;/li&gt;
&lt;li&gt;Je ne m'étendrai pas sur les redéfinitions covariantes qui n'existent pas en C# et auxquelles je préfère une conception à base de types paramétrés&lt;/li&gt;
&lt;li&gt;La prétendue "fragilité" due au manque de compatibilité binaire est un leurre. La compatibilité source est la seule qui a de l'importance à mes yeux pour définir (il faudra souvent le rappeler) des concepts d'implémentation&lt;/li&gt;
&lt;li&gt;L'existence de méthodes du même nom que les extensions est sans objet&amp;nbsp;: qui aurait intérêt à définir ce genre de doublons&amp;nbsp;?&lt;/li&gt;
&lt;li&gt;Le "not very object-oriented", c'est le "cherry on top". Est-ce que les lambdas expressions sont "very object-oriented" ???&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vous l'aurez compris&amp;nbsp;: je ne partage pas vraiment le point de vue de ces javaistes sur les extension methods de C#.&lt;br /&gt;
Mais voyons un peu ce qu'ils proposent pour faire mieux. Ils appelent ça les "Virtual Extension Methods". Cela consiste à fournir une implémentation par défaut à une méthode d'une interface.&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Exemple :&lt;br /&gt;&lt;/p&gt;
&lt;pre class="brush: java;"&gt;
interface List&amp;lt;T&gt; {
  // existing methods, plus
  void sort(Comparator&amp;lt;? super T&gt; cmp) default { Collections.sort(this, cmp); };
}
&lt;/pre&gt;



&lt;p&gt;A première vue, je me suis dit "pourquoi pas ?".&lt;br /&gt;
Cela fournit un mécanisme élégant pour faire des héritages de comportement et si ça permet de combler les défauts mineurs de l'extension par méthode statique, il n'y a pas de raison de s'en passer.&lt;br /&gt;
Mais j'ai quand même un peu réfléchi à la question et il y a quelques raisons qui me font penser que l'approche choisie par C# est bien meilleure.&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;Raison No 1&amp;nbsp;: l'extension de types existants&lt;/strong&gt;&lt;/p&gt;


&lt;p&gt;Imaginons que, dans notre exemple de code, nous ayons envie de simplifier l'écriture de la manière suivante&amp;nbsp;:&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;
List&amp;lt;Student&gt; students = ...
double highestScore =
    students.Where(s =&gt; s.GradYear == 2011)
                .Select(s =&gt; s.Score)
                .Max();
&lt;/pre&gt;



&lt;p&gt;En effet, le "Aggregate(0.0, Math.Max)" n'est pas un modèle de lisibilité et il gagnerait à être raccourci par le rajout d'une méthode qui renvoie le maximum d'une collection.&lt;/p&gt;


&lt;p&gt;En C#, cette fonction "Max" existe nativement mais, si elle n'existait pas, elle serait très facile à rajouter avec une SEM car celles-ci sont entièrement indépendantes des types auxquelles elles se rapportent&amp;nbsp;:&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;
static class MyIEnumerableExtension {
  static double Max(this IEnumerable&amp;lt;double&gt; self)
  {
     return self.Aggregate(0.0, Math.Max);
  }
}
&lt;/pre&gt;



&lt;p&gt;Allez donc faire ça avec les VEM de Java sans toucher à l'interface...&lt;br /&gt;
C'est d'ailleurs dingue ce que l'on peut faire dès que l'on a la possibilité de rajouter des méthodes à une interface sans toucher à celle-ci.&lt;br /&gt;
La future version de java aura de nouvelles méthodes filter/map/reduce dans ses collections mais comment être exhaustif et ne pas oublier toutes les méthodes qui pourraient être utiles ?&lt;br /&gt;
J'espère que ceux qui amélioreront les interfaces auront une bonne boule de cristal... Ils ne faudrait pas qu'ils oublient de mettre des méthodes de groupement et de mise en dictionnaire. Elles sont parfois si utiles.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
List&amp;lt;Student&gt; students = ...
Dictionary&amp;lt;double,IEnumerable&amp;lt;Student&gt;&gt; studentsByScore =
  students.GroupBy (s =&gt; s.Score)
          .ToDictionary (g =&gt; g.Key, g =&gt; g.AsEnumerable());
&lt;/pre&gt;


&lt;p&gt;&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;Raison No 2&amp;nbsp;: la maintenabilité au delà de la réutilisabilité&lt;/strong&gt;&lt;/p&gt;


&lt;p&gt;L'aspect le plus élégant des VEM (mixer du code et des interfaces) est aussi le plus dangereux en termes de maintenabilité.&lt;br /&gt;
Commençons par rappeler quelques principes &lt;a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod"&gt;énoncés par Uncle Bob&lt;/a&gt;&amp;nbsp;:&lt;/p&gt;


&lt;blockquote&gt;&lt;p&gt;&lt;ins&gt;Common Closure Principle&lt;/ins&gt;&lt;br /&gt;
The classes in a package should be closed together against the same kind of changes.&lt;br /&gt;
A change that affects a package affects all the classes in that package.&lt;/p&gt;&lt;/blockquote&gt;


&lt;blockquote&gt;&lt;p&gt;&lt;ins&gt;Stable Abstractions Principle&lt;/ins&gt;&lt;br /&gt;
Packages that are maximally stable should be maximally abstract.&lt;br /&gt;
Instable packages should be concrete.&lt;br /&gt;
The abstraction of a package should be in proportion to its stability.&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;Si l'on admet que le respect de ces principes (et de quelques autres) maximise la maintenabilité d'une application, alors on a un petit problème avec les VEM.&lt;br /&gt;
Mélanger une abstraction relativement stable avec un détail d'implémentation qui va plus souvent évoluer, fut-il un comportement par défaut, ne va pas dans le sens de regroupements maintenables.&lt;/p&gt;


&lt;p&gt;En clair, on est dans un des deux contextes suivants&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Soit les VEM ne sont utilisées qu'à la marge et on n'a pas de problème de maintenabilité. On peut alors se demander si les VEM sont une véritable stratégie du langage Java ou une simple réponse tactique au seul problème de la compatibilité des collections Java existantes avec le rajout filter/map/reduce...&lt;/li&gt;
&lt;li&gt;Soit les VEM sont amplement utilisées et elles sont alors une improbable invitation à mélanger abstraction stables et détails d'implémentation anéantissant ainsi tout effort allant vers plus de maintenabilité d'une application Java&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A l'inverse, les SEM de C# induisent une séparation claire entre les abstractions et les implémentations.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;&lt;strong&gt;Raison No 3&amp;nbsp;: une fonctionnalité pour les développeurs d'applications&lt;/strong&gt;&lt;/p&gt;


&lt;p&gt;Cette troisième raison est un peu le corollaire des deux raisons précédentes.&lt;br /&gt;
Brian Goetz écrit&amp;nbsp;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The whole point of extension methods is being able to compatibly evolve APIs&lt;br /&gt;
The key operation we care about is adding new methods with defaults to existing interfaces without necessarily recompiling the implementation class&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;Les solutions qu'il apporte vont clairement dans le sens de la facilitation d'écriture de librairie tierces et d'API&amp;nbsp;: &lt;ins&gt;les Virtual Extension Methods de Java ne sont qu'une fonctionnalité pour les développeurs de composants et de frameworks&lt;/ins&gt;&lt;br /&gt;
A l'inverse, avec leurs possibilités d'extension de types externes et de séparation abstraction/détail, &lt;ins&gt;les Static Extension Methods de C# sont une fonctionnalité pour les développeurs d'applications&lt;/ins&gt;.&lt;/p&gt;


&lt;p&gt;On pourra argumenter que c'est important d'avoir des composant tiers extensibles qui ne cassent pas la compatibilité binaire et qu'à ce titre, les VEM sont un bon choix.&lt;br /&gt;
A cela, je suis tenté de répondre&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;que l'extensibilité grace aux VEM est plus que relative (on ne peut pas rajouter une méthode à une interface sans casser la compatibilité binaire...)&lt;/li&gt;
&lt;li&gt;que le mécanisme IQueryable de C#/.NET qui est un des fondements de LINQ offre des possibilités bien supérieures si on tient absolument à écrire des composants binairement indépendants avec des fonctionnalités d'un tout autre ordre (récupération dynamique de l'arbre d'expression sous-jacent aux appels extension methods + lambdas)&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/20/#pnote-452-5" id="rev-pnote-452-5"&gt;5&lt;/a&gt;]&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ma conclusion est simple&amp;nbsp;: le choix VEM vs SEM est un peu le reflet de l'écosystème dans lequel chacun des langages évolue.&lt;br /&gt;
En tant que développeur d'applications, je suis bien content d'utiliser C# et ses extensions statiques qui facilitent ma vie de tous les jours. Je laisse volontiers les Virtual Extension Methods aux amoureux des frameworks en tout genre et aux adeptes des armées de librairies à tout faire et à assembler "comme on peut"...&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/20/#rev-pnote-452-1" id="pnote-452-1"&gt;1&lt;/a&gt;] troll inside&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/20/#rev-pnote-452-2" id="pnote-452-2"&gt;2&lt;/a&gt;] Et si je fais des erreurs dans ce billet, je ne doute pas qu'un javaiste de passage saura me le faire remarquer...&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/20/#rev-pnote-452-3" id="pnote-452-3"&gt;3&lt;/a&gt;] J'ai écrit récemment une série de billets sur le sujet. &lt;a href="http://agilitateur.azeau.com/post/2012/03/05/Conception-logicielle"&gt;Le premier est là&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/20/#rev-pnote-452-4" id="pnote-452-4"&gt;4&lt;/a&gt;] Il y aurait un billet entier à faire sur "comment se passer de la réflexion sur les méthodes"&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/20/#rev-pnote-452-5" id="pnote-452-5"&gt;5&lt;/a&gt;] Il faudrait là aussi un billet complet pour montrer le polymorphisme introduit en C# par LINQ&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/03/20/La-fausse-bonne-id%C3%A9e-des-Virtual-Extension-Methods-dans-Java-8#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/03/20/La-fausse-bonne-id%C3%A9e-des-Virtual-Extension-Methods-dans-Java-8#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/452</wfw:commentRss>
      </item>
    
  <item>
    <title>Les logiciels petits sont les plus jolis</title>
    <link>http://agilitateur.azeau.com/post/2012/03/09/Les-logiciels-petits-sont-les-plus-jolis</link>
    <guid isPermaLink="false">urn:md5:bf513bd8b32062d01ddf8dd2778b60ca</guid>
    <pubDate>Fri, 09 Mar 2012 08:08:00 +0100</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
        <category>craftsmanship</category><category>software design</category>    
    <description>    &lt;p&gt;Cinquième billet et dernier billet de cette série sur la conception de logiciels&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/09/#pnote-448-1" id="rev-pnote-448-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;&lt;br /&gt;
Que se passe-t-il lorsqu'un logiciel grossit ?&lt;br /&gt;
Est-on en mesure d'introduire indéfiniment de nouveaux concepts et de conserver un ensemble toujours aussi évolutif&amp;nbsp;?&lt;/p&gt;


&lt;p&gt;Je ne crois pas que cela soit possible car&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cela nécessiterait une équipe de plus en plus grosse pour gérer la base de code&lt;/li&gt;
&lt;li&gt;et cela demanderait un effort monumental pour garantir la cohérence fonctionnelle de l'ensemble&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Je sais que, dans certains endroits, plusieurs équipes travaillent simultanément sur la même base de code, chaque équipe étant en charge de fonctionnalités bien définies. On parle alors d'"équipe feature"&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/09/#pnote-448-2" id="rev-pnote-448-2"&gt;2&lt;/a&gt;]&lt;/sup&gt;. Je n'ai jamais expérimenté cela et je reste dubitatif sur l'efficacité de la chose.&lt;br /&gt;
Il m'est arrivé de travailler sur de gros logiciels mais le développement de ceux-ci était toujours organisé en composants, chaque composant ayant sa base de code propre et son équipe dédiée, y compris au niveau fonctionnel&amp;nbsp;: un chef de produit et un backlog produit par composant.&lt;/p&gt;


&lt;p&gt;La plus grande qualité que je trouve aux composants logiciels, c'est qu'ils permettent à la base de code d'un logiciel de rester dans une taille raisonnable. Cela se réalise en considérant chaque composant comme un logiciel à part entière avec ses propres exigences et ses propres concepts.&lt;br /&gt;
A mon avis, le seul risque de cette approche est de définir des composants trop en amont dans le développement d'un logiciel, ce qui pourrait amener à des choix qui se marient mal avec les concepts du logiciel décomposé.&lt;br /&gt;
Mais si on laisse faire les choses et que l'on découpe au moment opportun, le risque disparait.&lt;/p&gt;


&lt;p&gt;Exemple&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1- Le code d'un logiciel a été simplifié grace à un concept d'implémentation&lt;/li&gt;
&lt;li&gt;2- Après quelques évolution du logiciel, le concept sous-jacent commence à grossir&lt;/li&gt;
&lt;li&gt;3- Il grossit tellement qu'il commence lui-même à être organisé avec des abstractions et des détails&lt;/li&gt;
&lt;li&gt;4- Il devient alors &lt;ins&gt;un produit logiciel à part entière&lt;/ins&gt; où une partie de ses concepts d'architecture sont l'API qui permet de l'utiliser&lt;/li&gt;
&lt;li&gt;5- Notre logiciel est revenu à sa taille initiale (voire à une taille plus petite) car il utilise un produit tiers qui a son propre cycle de vie&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/5x01.png" alt="5x01.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Autre exemple&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1- Un gros logiciel est défini par ses concepts d'architecture et ses détails d'implémentation&lt;/li&gt;
&lt;li&gt;2- Une partie de ce logiciel est fortement découplée du reste (le lien ne se fait que par quelques abstractions)&amp;nbsp;: elle est naturellement organisée comme si elle était un produit à part entière, les quelques abstraction formant le lien étant l'API du produit distinct&lt;/li&gt;
&lt;li&gt;3- On donne sa liberté à ce produit et le logiciel initial retourne une taille raisonnable tout en ayant limité le lien avec le nouveau produit tiers à un seul de ses détails d'implémentation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/5x02.png" alt="5x02.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;On voit donc que l'émergence de produits tiers à partir de morceaux d'un logiciel existant peut être intéressante si elle respecte le découpage naturel du logiciel, c'est à dire si elle se base sur des concepts qui ont déjà émergé. Par ailleurs, comme nos jeux de tests se basent sur les concepts, qu'ils soient d'architecture ou d'implémentation, les nouveaux produits débutent leur existence avec des jeux de tests qui expriment clairement leur comportement.&lt;/p&gt;


&lt;p&gt;Il existe toutefois des cas où les choses ne sont pas aussi simples.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1- Prenons un logiciel qui, à travers ses concepts d'architecture, propose une API et la possibilité d'être étendu par divers détails présentés comme des "plugins"&lt;/li&gt;
&lt;li&gt;2- Si ces plugins venaient à grossir, on ne pourrait pas les considérer comme des produits tiers dont dépend le logiciel car l'API fait partie du logiciel et les plugins en dépendent. Une solution est alors de considérer notre le logiciel initial comme un produit tiers.&lt;/li&gt;
&lt;li&gt;3- En faisant cela, les plugins deviennent notre logiciel principal qui va pouvoir grossir en dépendant du produit tiers nouvellement créé. Cette opération est toutefois délicate car l'API qui sert désormais de point d'entrée au produit tiers n'est pas forcément adaptée à cela et, du fait de l'orientation "plugins", elle ne possède peut être pas les jeux de tests adéquats.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/5x03.png" alt="5x03.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Cela reste une exemple. On pourrait avoir un plugin qui grossirait par introduction d'un concept d'implémentation lequel deviendrait à son tour un produit à part entière (cf 1er exemple du billet).&lt;br /&gt;
On retiendra que le concept d'architecture de type "API qui permet d'étendre un logiciel", ça peut être sympa sur le moment mais ça peut engendrer des inconvénients à plus long terme en fonction de la façon dont on appréhende le développement des plugins.&lt;/p&gt;


&lt;p&gt;Voilà...&lt;br /&gt;
Ainsi s'achève cette série sur la conception de logiciels, ou devrais-je plutôt dire sur ma vision, en ce début d'année 2012, de ce qui me semble primordial dans la réalisation d'un logiciel. J'espère que cela aura intéressé quelques personnes. J'espère aussi avoir quelques retours qu'ils soient positifs ou négatifs. En tout cas, cela aura bien occupé mon temps libre de la semaine&amp;nbsp;!&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/09/#rev-pnote-448-1" id="pnote-448-1"&gt;1&lt;/a&gt;] Les quatre premiers billets sont là : &lt;a href="http://agilitateur.azeau.com/post/2012/03/05/Conception-logicielle"&gt;Conception logicielle&lt;/a&gt; ; &lt;a href="http://agilitateur.azeau.com/post/2012/03/06/Le-logiciel%2C-un-organisme-multicellulaire"&gt;Le logiciel, un organisme multicellulaire ?&lt;/a&gt; ; &lt;a href="http://agilitateur.azeau.com/post/2012/03/07/Chacun-cherche-son-TDD"&gt;Chacun cherche son TDD&lt;/a&gt; ; &lt;a href="http://agilitateur.azeau.com/post/2012/03/08/Le-logiciel-d-un-d%C3%A9veloppeur-est-son-ch%C3%A2teau"&gt;Le logiciel d'un développeur est son château&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/09/#rev-pnote-448-2" id="pnote-448-2"&gt;2&lt;/a&gt;] L'article "Feature Team Primer" dont une traduction par Fabrice Aimetti est disponible ici : &lt;a href="http://www.fabrice-aimetti.fr/dotclear/index.php?post/2011/06/13/Equipe-feature"&gt;http://www.fabrice-aimetti.fr/dotclear/index.php?post/2011/06/13/Equipe-feature&lt;/a&gt; présente ce genre d'organisation mais, pour moi, les auteurs avancent des arguments qui reposent entièrement sur une définition que je ne partage pas de ce qu'est une "architecture". Il faudrait un billet complet pour détailler ce sujet...&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/03/09/Les-logiciels-petits-sont-les-plus-jolis#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/03/09/Les-logiciels-petits-sont-les-plus-jolis#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/448</wfw:commentRss>
      </item>
    
  <item>
    <title>Le logiciel d'un développeur est son château</title>
    <link>http://agilitateur.azeau.com/post/2012/03/08/Le-logiciel-d-un-d%C3%A9veloppeur-est-son-ch%C3%A2teau</link>
    <guid isPermaLink="false">urn:md5:f15bdacef2c83e425a0b33d96ad2415f</guid>
    <pubDate>Thu, 08 Mar 2012 08:08:00 +0100</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
        <category>craftsmanship</category><category>software design</category>    
    <description>    &lt;p&gt;Quatrième billet de la série sur la conception de logiciels&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/08/#pnote-451-1" id="rev-pnote-451-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;&lt;/p&gt;


&lt;p&gt;Je n'ai pas encore abordé la question des éléments tiers dans la réalisation d'un logiciel.&lt;br /&gt;
Il y a une bonne raison à cela&amp;nbsp;: je crois fermement que c'est un point de détail qui ne mérite pas une place trop importante.&lt;/p&gt;


&lt;p&gt;Quand on discute sur les méthodes agiles et sur la capacité de pouvoir remettre en cause à tout moment le comportement de l'existant pour satisfaire au besoin le plus prioritaire d'un produit logiciel, il y a toujours quelqu'un pour dire "Oui on peut faire des changements mais il y a quand même des choix d'architecture que l'on ne peut pas facilement modifier". Et bien souvent il y a quelqu'un pour rajouter "c'est pourquoi il faut définir l'architecture dans la première itération". Il m'est arrivé plusieurs fois d'entendre cela et je ne partage pas du tout cet avis.&lt;/p&gt;


&lt;p&gt;Cette divergence de points de vue est simple à comprendre&amp;nbsp;: tout le monde ne met pas la même chose derrière le mot "architecture".&lt;/p&gt;


&lt;p&gt;Choisir un SGBDR X ou Y ou choisir un stockage "NoSQL", ce n'est pas faire un choix d'architecture, c'est faire le choix des détails d'un mécanisme de persistance.&lt;br /&gt;
Choisir un framework web Y ou Z, ce n'est pas faire un choix d'architecture, c'est faire le choix des détails d'un mécanisme de diffusion de données.&lt;/p&gt;


&lt;p&gt;Comme le dit l'académie française&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/08/#pnote-451-2" id="rev-pnote-451-2"&gt;2&lt;/a&gt;]&lt;/sup&gt;, l'architecture, c'est la disposition, l'ordonnance d'un édifice. Les choix d'architecture doivent représenter ce qui est fondamental -et rien d'autre- dans un logiciel, ce qui constitue sa nature, des choses telles que la modélisation du domaine métier ou la formalisation des principales opérations réalisées par le logiciel.&lt;br /&gt;
Cette approche permet de garantir un point essentiel de l'architecture&amp;nbsp;: sa stabilité. Sous certaines conditions, cette stabilité ne remet pas en cause la capacité à modifier un comportement et elle offre la possibilité de changer de mécanisme de persistance ou de diffusion à tout moment dans la (longue) vie du logiciel.&lt;/p&gt;


&lt;p&gt;Une des conditions est que les concepts d'architecture ne doivent pas dépendre de logiciels tiers. Bien evidemment la suppression de toutes les dépendances est impossible&amp;nbsp;: si les concepts d'architecture sont exprimés dans un langage informatique, ils dépendent, au minimum, de la syntaxe de ce langage et d'un interpréteur/compilateur/runtime associé. Idéalement, il ne devrait y avoir aucune autre dépendance.&lt;/p&gt;


&lt;p&gt;En résumé, un logiciel est à son développeur ce que sa maison est à un anglais&amp;nbsp;: son château, c'est à dire un endroit où il n'a pas à subir les invasions de logiciels tiers et de leurs hordes de contraintes.&lt;/p&gt;


&lt;p&gt;Si tout cela est acquis, seuls les concepts et les détails d'implémentation dépendent des logiciels tiers (représentés en vert dans le schema qui suit).&lt;br /&gt;
La dépendance à un tiers donné se limite alors à un élément précis et ne s'éparpille pas dans tous les détails du logiciel. Les concepts d'implémentation peuvent centraliser ces dépendances le cas échéant.&lt;/p&gt;


&lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/4x01.png" alt="4x01.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Voilà réglée de manière un peu radicale la question des tiers.&lt;br /&gt;
Il va sans dire que certaines pratiques désormais courantes, telles que prendre un framework tiers pour constituer l'ossature d'un logiciel, me font hurler...&lt;/p&gt;


&lt;p&gt;Le &lt;a href="http://agilitateur.azeau.com/post/2012/03/09/Les-logiciels-petits-sont-les-plus-jolis"&gt;prochain billet&lt;/a&gt; abordera un sujet connexe&amp;nbsp;: le cas des GROS logiciels et de leur possible décomposition...&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/08/#rev-pnote-451-1" id="pnote-451-1"&gt;1&lt;/a&gt;] Les trois premiers billets sont là : &lt;a href="http://agilitateur.azeau.com/post/2012/03/05/Conception-logicielle"&gt;Conception logicielle&lt;/a&gt; ; &lt;a href="http://agilitateur.azeau.com/post/2012/03/06/Le-logiciel%2C-un-organisme-multicellulaire"&gt;Le logiciel, un organisme multicellulaire ?&lt;/a&gt; et &lt;a href="http://agilitateur.azeau.com/post/2012/03/07/Chacun-cherche-son-TDD"&gt;Chacun cherche son TDD&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/08/#rev-pnote-451-2" id="pnote-451-2"&gt;2&lt;/a&gt;] cf premier billet de la série : &lt;a href="http://agilitateur.azeau.com/post/2012/03/05/Conception-logicielle"&gt;Conception logicielle&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/03/08/Le-logiciel-d-un-d%C3%A9veloppeur-est-son-ch%C3%A2teau#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/03/08/Le-logiciel-d-un-d%C3%A9veloppeur-est-son-ch%C3%A2teau#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/451</wfw:commentRss>
      </item>
    
  <item>
    <title>Chacun cherche son TDD</title>
    <link>http://agilitateur.azeau.com/post/2012/03/07/Chacun-cherche-son-TDD</link>
    <guid isPermaLink="false">urn:md5:d3ad7f1458ca22511acfd4a76f8f3e93</guid>
    <pubDate>Wed, 07 Mar 2012 08:08:00 +0100</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
        <category>craftsmanship</category><category>software design</category>    
    <description>    &lt;p&gt;Ce billet est le troisième d'une série sur la conception de logiciels&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/07/#pnote-447-1" id="rev-pnote-447-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;Après avoir parlé de l'évolution d'un logiciel et de l'émergence des divers concepts qui le composent, voyons comment un développeur peut maitriser cette évolution.
Le meilleur outil que je connaisse aujourd'hui pour cela, c'est le développement piloté par les tests&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/07/#pnote-447-2" id="rev-pnote-447-2"&gt;2&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;Beaucoup de choses ont été écrites sur le TDD et ce billet sera donc un énième point de vue (le mien) sur le sujet.&lt;br /&gt;
Des reproches lui sont régulièrement faits&amp;nbsp;: "le nombre de tests à écrire est trop coûteux", "le TDD est une mauvaise approche car il est inutile de tester toutes les fonctions/toutes les méthodes de toutes les classes", ...&lt;br /&gt;
Ces points de vue me donnent au moins une certitude&amp;nbsp;: tout le monde ne met pas la même chose derrière le mot TDD.&lt;/p&gt;


&lt;p&gt;En ce qui me concerne, le TDD me sert à deux choses&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1- faire émerger et peaufiner les concepts d'un logiciel, aussi bien ceux d'architecture que d'implémentation&lt;/li&gt;
&lt;li&gt;2- vérifier le comportement des détails d'implémentation au travers des concepts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Le premier point est la conséquence directe de l'évolution naturelle d'un logiciel par conception émergente.&lt;br /&gt;
Regardons comment peuvent apparaitre des concepts d'architecture lors d'un pilotage par les tests.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1- On a un test vide&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;2- On commence à écrire le test&amp;nbsp;: un début de concept apparait pour accéder aux détails à venir&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;3- Les détails apparaissent. On passe alors par plusieurs phase red-green-refactor qui vont faire évoluer à la fois l'implémentation et le concept pour arriver à un résultat satisfaisant&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;4- On introduit d'autres scénarios de test. Lors des red-green-refactor, d'autres concepts apparaissent&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;5- Les concepts ont permis de diviser les détails. Une partie peut alors être avantageusement remplacée par une doublure pour favoriser la croissance ultérieure du logiciel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/3x01.png" alt="3x01.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;L'apparition de nouveaux concepts d'architecture est le cas de figure idéal pour découpler les détails d'implémentation mais elle n'est jamais garantie.&lt;br /&gt;
Quand des détails deviennent trop complexes, il reste la possibilité d'introduire de nouveaux concepts d'implémentation comme dans l'exemple suivant.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1- On a un test vide&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;2- On commence à écrire le test&amp;nbsp;: un début de concept apparait pour accéder aux détails à venir&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;3- Les détails apparaissent. On passe alors par plusieurs phase red-green-refactor qui vont faire évoluer à la fois l'implémentation et le concept pour arriver à un résultat satisfaisant&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;4- On introduit d'autres scénarios de test. Lors des red-green-refactor, le code se complexifie&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;5- On travaille sur un nouveau concept d'implémentation pour simplifier le code. Pour cela, on rajoute des tests ad-hoc et on fait évoluer en parallèle le nouveau concept et son utilisation&amp;nbsp;;&lt;/li&gt;
&lt;li&gt;6- Le nouveau concept finit par remplacer complètement le code trop complexe.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/3x02.png" alt="3x02.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Le point délicat de ces phases d'émergence est que, bien évidemment, les tests existants portent sur des concepts existants. Toute la difficulté réside dans la création de jeux de tests portant sur les nouveaux concepts. Cela nécessite soit de mener en parallèle l'émergence et la constitution des nouveaux tests, soit de les écrire a posteriori.&lt;br /&gt;
En l'occurrence, dans le premier exemple on n'a pas introduit de scenarios de tests utilisant le dernier concept créé pour vérifier les détails qui ont été séparés. Cela doit être fait immédiatement après pour permettre à ces détails de continuer à croitre sereinement.&lt;/p&gt;


&lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/3x03.png" alt="3x03.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Une caractéristique commune à tous les tests de ces exemples est qu'ils ne dépendent que des concepts, jamais des détails.&lt;br /&gt;
Pour moi, c'est un point important. &lt;ins&gt;Les tests sont écrits en utilisant des notions stables.&lt;/ins&gt; Cela permet à la fois d'écrire des tests qui résisteront mieux à l'épreuve du temps et de les exprimer avec un vocabulaire clairement défini. Un test, ce n'est pas juste du code qui affiche une bande verte ou une bande rouge, c'est surtout un moyen de décrire intelligiblement le comportement du logiciel.&lt;/p&gt;


&lt;p&gt;A l'usage, la manière d'écrire les tests diffère sensiblement selon que l'on manipule des concepts d'architecture ou des concepts d'implémentation.&lt;br /&gt;
Les concepts d'implémentation sont très proches des détails du code. Je trouve que les outils de type xUnit&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/07/#pnote-447-3" id="rev-pnote-447-3"&gt;3&lt;/a&gt;]&lt;/sup&gt; se prêtent bien à l'écriture des tests qui y sont rattachés. Ils permettent de construire des concepts qui utilisent un maximum de possibilités du langage utilisé (par exemple, pour des fluent interfaces&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/07/#pnote-447-4" id="rev-pnote-447-4"&gt;4&lt;/a&gt;]&lt;/sup&gt;)&lt;/p&gt;


&lt;p&gt;Les concepts d'architecture constituent le langage commun aux divers éléments d'un logiciel et, par extension, aux personnes qui participent au développement de ce logiciel. C'est en utilisant ce langage que l'on peut écrire des spécifications exécutables. Les concepts peuvent ainsi être paramétrés dans des outils de spécification exécutables de type 'scenario' (cucumber, specflow, jbehave...)&lt;br /&gt;
Typiquement, on pourra créer une bibliothèque de doublures dont les étapes d'initialisation seront utilisées dans les pré-conditions d'un scenario. On peut ainsi se constituer un "DSL" de spécifications pour notre logiciel. En se basant uniquement sur les concepts d'architecture, on peut écrire tous les scénarios utiles dans un langage naturel sans avoir à systématiquement détailler les étapes dans du code spécifique.&lt;br /&gt;
J'ai trop peu d'expérience avec les outils de spécification de type 'document' (fitnesse, concordion...) mais je suppose que l'on peut les utiliser de la même manière.&lt;/p&gt;


&lt;p&gt;Emergence de la conception... Pilotage par les tests... Tout cela marche souvent très bien quand on écrit du code qui fonctionne en autarcie. Les choses peuvent être légèrement différentes quand il s'agit d'interagir avec des logiciels tiers&lt;br /&gt;
Dans &lt;a href="http://agilitateur.azeau.com/post/2012/03/08/Le-logiciel-d-un-d%C3%A9veloppeur-est-son-ch%C3%A2teau"&gt;le prochain billet&lt;/a&gt;, j'essaierai donc de parler des relations qu'un logiciel entretient avec son environnement.&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/07/#rev-pnote-447-1" id="pnote-447-1"&gt;1&lt;/a&gt;] Les deux premiers billets sont là : &lt;a href="http://agilitateur.azeau.com/post/2012/03/05/Conception-logicielle"&gt;Conception logicielle&lt;/a&gt; et &lt;a href="http://agilitateur.azeau.com/post/2012/03/06/Le-logiciel%2C-un-organisme-multicellulaire"&gt;Le logiciel, un organisme multicellulaire ?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/07/#rev-pnote-447-2" id="pnote-447-2"&gt;2&lt;/a&gt;] &lt;a href="http://fr.wikipedia.org/wiki/Test_Driven_Development"&gt;http://fr.wikipedia.org/wiki/Test_Driven_Development&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/07/#rev-pnote-447-3" id="pnote-447-3"&gt;3&lt;/a&gt;] &lt;a href="http://en.wikipedia.org/wiki/XUnit"&gt;http://en.wikipedia.org/wiki/XUnit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/07/#rev-pnote-447-4" id="pnote-447-4"&gt;4&lt;/a&gt;] &lt;a href="http://en.wikipedia.org/wiki/Fluent_interface"&gt;http://en.wikipedia.org/wiki/Fluent_interface&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/03/07/Chacun-cherche-son-TDD#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/03/07/Chacun-cherche-son-TDD#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/447</wfw:commentRss>
      </item>
    
  <item>
    <title>Le logiciel, un organisme multicellulaire ?</title>
    <link>http://agilitateur.azeau.com/post/2012/03/06/Le-logiciel%2C-un-organisme-multicellulaire</link>
    <guid isPermaLink="false">urn:md5:be3ea7dbe4a2c8521843203cd70e20de</guid>
    <pubDate>Tue, 06 Mar 2012 08:08:00 +0100</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
        <category>craftsmanship</category><category>software design</category>    
    <description>    &lt;p&gt;Ce billet est le deuxième d'une série sur le conception de logiciels&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/06/#pnote-446-1" id="rev-pnote-446-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;


&lt;p&gt;Je m'intéresse aujourd'hui à la manière dont évolue la structure d'un logiciel, notamment en ce qui concerne les concepts dont on a pu parler précédemment.&lt;/p&gt;


&lt;p&gt;Il y a fort longtemps, les cours que j'ai pu avoir en relation avec le développement logiciel avaient toujours une approche assez constructiviste&amp;nbsp;: avant d'écrire la moindre ligne de code, on commence par découper un problème donné en problèmes élémentaires, puis on réfléchit aux concepts que l'on va utiliser, ensuite on commence a écrire des bouts de code que l'on va assembler pour parvenir au logiciel final.&lt;/p&gt;


&lt;p&gt;En suivant cette démarche, on commence par définir l'architecture du logiciel avant d'en réaliser les détails&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/2x01.png" alt="2x01.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Et même au niveau des détails, on est amené à suivre la même approche. On commence par implémenter quelques concepts de base avant de les assembler&amp;nbsp;:&lt;/p&gt;


&lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/2x02.png" alt="2x02.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Cette approche a le mérite d'être analogue à certains domaines de l'ingénierie ("on crée le plan avant de réaliser l'ouvrage") mais, en ce qui me concerne, elle survit difficilement à la réalité du développement logiciel.&lt;br /&gt;
Je n'ai jamais vu quelqu'un bâtir intégralement un logiciel comme on construirait une maison. A un moment ou à un autre, le logiciel dévie sensiblement du moindre plan que l'on aurait pu faire. En fait, par certains aspects, un logiciel ressemble à un organisme...&lt;/p&gt;


&lt;blockquote&gt;&lt;p&gt;Organisme&amp;nbsp;: entité biologique, unicellulaire ou pluricellulaire, capable de se développer et de se reproduire.&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;Dans le phénomène probablement le plus connu de la reproduction cellulaire, la mitose&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/06/#pnote-446-2" id="rev-pnote-446-2"&gt;2&lt;/a&gt;]&lt;/sup&gt;, une cellule croit et se divise pour au final donner deux cellules génétiquement identiques mais qui peuvent être fonctionnellement différenciées.&lt;/p&gt;


&lt;p&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/33/%C3%89v%C3%A9nements_importants_en_mitose.svg/350px-%C3%89v%C3%A9nements_importants_en_mitose.svg.png" alt="Mitose" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Il en va un peu de même pour la formation des concepts d'architecture d'un logiciel. Lorsqu'une implémentation grossit, des abstractions apparaissent et, si tout se passe bien, l'implémentation se divise en deux parties indépendantes mais rattachées par ces nouvelles abstractions.&lt;/p&gt;


&lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/2x03.png" alt="2x03.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Pour rester dans le même type d'analogie, on pourrait aussi évoquer la réparation d'une plaie cutanée&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/06/#pnote-446-3" id="rev-pnote-446-3"&gt;3&lt;/a&gt;]&lt;/sup&gt;&amp;nbsp;: l'organisme s'auto-répare lorsque survient une blessure légère.&lt;/p&gt;


&lt;p&gt;Dans un logiciel, le code blessé est celui qui, devenu trop complexe, ne peut plus évoluer correctement. L'émergence de concepts d'implémentation répare le code et lui permet d'aller de l'avant.&lt;/p&gt;


&lt;p&gt;&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/2x04.png" alt="2x04.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Bref, même si de bons concepts peuvent être pensés a priori, il ne faut pas abuser de la chose. Un logiciel qui évolue harmonieusement à partir de besoins de conceptualisation avérés (une abstraction qui émerge, une implémentation qui se simplifie) a de meilleures chances d'évoluer et croitre qu'une créature de Frankenstein assemblée à partir de morceaux choisis en amont.&lt;/p&gt;


&lt;p&gt;Le défi dans l'évolution d'un logiciel, c'est la manière dont un développeur arrive à la contrôler. &lt;a href="http://agilitateur.azeau.com/post/2012/03/07/Chacun-cherche-son-TDD"&gt;Cela sera le sujet d'un prochain billet&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/06/#rev-pnote-446-1" id="pnote-446-1"&gt;1&lt;/a&gt;] Le premier billet est là : &lt;a href="http://agilitateur.azeau.com/post/2012/03/05/Conception-logicielle"&gt;Conception logicielle&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/06/#rev-pnote-446-2" id="pnote-446-2"&gt;2&lt;/a&gt;] &lt;a href="http://fr.wikipedia.org/wiki/Mitose"&gt;http://fr.wikipedia.org/wiki/Mitose&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/06/#rev-pnote-446-3" id="pnote-446-3"&gt;3&lt;/a&gt;] &lt;a href="http://www.chups.jussieu.fr/polys/histo/histoP2/POLY.Chp.5.6.html"&gt;http://www.chups.jussieu.fr/polys/histo/histoP2/POLY.Chp.5.6.html&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/03/06/Le-logiciel%2C-un-organisme-multicellulaire#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/03/06/Le-logiciel%2C-un-organisme-multicellulaire#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/446</wfw:commentRss>
      </item>
    
  <item>
    <title>Conception logicielle</title>
    <link>http://agilitateur.azeau.com/post/2012/03/05/Conception-logicielle</link>
    <guid isPermaLink="false">urn:md5:fdd4209d951fbf97883ac99c94e45a63</guid>
    <pubDate>Mon, 05 Mar 2012 08:08:00 +0100</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
        <category>craftsmanship</category><category>software design</category>    
    <description>    &lt;p&gt;Une pratique utile à tout développeur de logiciels est l'analyse de son propre travail&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#pnote-445-1" id="rev-pnote-445-1"&gt;1&lt;/a&gt;]&lt;/sup&gt;. C'est dans cet esprit que j'entame aujourd'hui une petite série de billets sur la conception de logiciels, ou, plus précisément, ce qu'est, à cet instant, pour moi, la conception de logiciels.&lt;br /&gt;
C'est à la fois une façon de faire un point personnel sur ce que j'ai appris&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#pnote-445-2" id="rev-pnote-445-2"&gt;2&lt;/a&gt;]&lt;/sup&gt;, de le partager avec tous ceux qui pourraient être intéressés&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#pnote-445-3" id="rev-pnote-445-3"&gt;3&lt;/a&gt;]&lt;/sup&gt;, et enfin de l'exposer à la critique publique de ceux qui prendront le temps de le lire&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#pnote-445-4" id="rev-pnote-445-4"&gt;4&lt;/a&gt;]&lt;/sup&gt;.&lt;br /&gt;
Dans cette série de billets, je compte donc aborder les points qui me paraissent les plus importants dans la conception, la manière dont ils évoluent au fil du temps, le contrôle qu'exerce un développeur sur cette évolution et les relations qu'entretient le logiciel avec son environnement.&lt;/p&gt;


&lt;p&gt;Avant de parler de "conception" logicielle, il me faut définir le terme.&lt;br /&gt;
Le dictionnaire de l'académie française&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#pnote-445-5" id="rev-pnote-445-5"&gt;5&lt;/a&gt;]&lt;/sup&gt; propose plusieurs définition pour la conception. Celle-ci me parait adaptée.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Conception&amp;nbsp;: Action de former le concept d'un objet&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;Allons voir la définition d'un concept. Il y en a, là aussi, plusieurs mais je prends celle qui me convient le mieux&amp;nbsp;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Concept&amp;nbsp;: Construction de l'esprit explicitant un ensemble stable de caractères communs désigné par un signe verbal.&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;Ainsi, j'ai envie de dire que &lt;ins&gt;concevoir un logiciel, c'est nommer et décrire ce que partagent les divers éléments qui le composent&lt;/ins&gt;. Ce partage induit une dépendance des divers éléments, les détails, envers ce qu'ils ont en commun.
&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/1x01.png" alt="1x01.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Ceci étant, tous les concepts n'ont pas la même nature. J'en distingue deux&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Certains concepts sont omniprésent sur l'ensemble du logiciel. Ils permettent de décrire, par exemple, le domaine métier que le logiciel manipule&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#pnote-445-6" id="rev-pnote-445-6"&gt;6&lt;/a&gt;]&lt;/sup&gt; ou encore les contrats que respectent les divers éléments quand ils dialoguent les uns avec les autres&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#pnote-445-7" id="rev-pnote-445-7"&gt;7&lt;/a&gt;]&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;D'autres concepts n'ont de raison d'être que par rapport à une tactique de réalisation du logiciel. Un élément va, par exemple, utiliser une évaluation paresseuse&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#pnote-445-8" id="rev-pnote-445-8"&gt;8&lt;/a&gt;]&lt;/sup&gt; pour optimiser les performances&amp;nbsp;; d'autres élements aux algorithmes similaires vont partager un patron de méthode&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#pnote-445-9" id="rev-pnote-445-9"&gt;9&lt;/a&gt;]&lt;/sup&gt;&amp;nbsp;; etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Intéressons-nous au premier cas. Les concepts omniprésents sont la base sans laquelle le logiciel ne pourrait exister. Ils décrivent la manière dont les élements de détail sont agencés les uns par rapport aux autres. Il y a un mot qui me rappelle cette idée de mise en forme globale d'une construction&amp;nbsp;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Architecture&amp;nbsp;: Disposition, ordonnance d'un édifice.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;On pourrait donc parler de &lt;ins&gt;concepts d'architecture&lt;/ins&gt;.&lt;/p&gt;


&lt;p&gt;Faisons un zoom sur le schema précédent pour apercevoir les packages qui composent le logiciel. On entend ici par package des bouts de code dont le contenu est lié par un destin commun, tant du point de vue de l'utilisation que de la modification&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#pnote-445-10" id="rev-pnote-445-10"&gt;10&lt;/a&gt;]&lt;/sup&gt;. On a, en bleu, les packages contenant les concepts d'architecture et, en rouge, les détails de réalisation du logiciel.
&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/1x02.png" alt="1x02.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Faisons un aparté rapide pour préciser que l'association implicite "concept &amp;lt;-&amp;gt; bouts de code" n'a rien d'étonnant. On peut dessiner un concept sur un tableau&amp;nbsp;; on peut le décrire dans un document mais s'il n'est pas présent explicitement dans le code, il n'existe pas&amp;nbsp;!&lt;/p&gt;


&lt;p&gt;Si on fait un nouveau zoom, on découvre les &lt;ins&gt;concepts d'implémentation&lt;/ins&gt; qui constituent les choix de construction des détails. A priori, ces concepts sont internes aux packages de détails car l'utilisation d'un entre eux dans un package n'a aucune implication sur les autres packages. Sur le schéma suivant, les concepts d'implémentation sont représentés en beige.
&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/1x03.png" alt="1x03.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;Toutefois, il arrive que certains de ces concepts soient utilisés dans plusieurs situations indépendantes. Ils intègrent alors, pour des raisons pratiques, des packages partagés.
&lt;img src="http://agilitateur.azeau.com/public/agilitateur/software_design/1x04.png" alt="1x04.png" style="display:block; margin:0 auto;" /&gt;&lt;/p&gt;


&lt;p&gt;On se retrouve ainsi avec plusieurs niveaux de définition d'un logiciel sur lesquels on doit pouvoir vérifier les progressions habituelles d'abstraction et de stabilité&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#pnote-445-11" id="rev-pnote-445-11"&gt;11&lt;/a&gt;]&lt;/sup&gt;.&lt;/p&gt;
&lt;table&gt;
&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Concepts d'architecture&lt;/th&gt;&lt;th&gt;Concepts d'implémentation&lt;/th&gt;&lt;th&gt;Détails d'implémentation&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Dépendances&lt;/th&gt;&lt;td&gt;Ne dépendent que d'autres concepts d'architecture&lt;/td&gt;&lt;td&gt;Peuvent dépendre de concepts d'architecture ou de d'autres concepts d'implémentation&lt;/td&gt;&lt;td&gt;Dépendent de concepts d'architecture et de concepts d'implémentation&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Niveau d'abstraction&lt;/th&gt;&lt;td&gt;Entièrement abstraits&lt;/td&gt;&lt;td&gt;Mélange d'abstraction et de détails&lt;/td&gt;&lt;td&gt;Entièrement composés de détails&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Niveau de stabilité&lt;/th&gt;&lt;td&gt;Stabilité maximale&lt;/td&gt;&lt;td&gt;Partiellement stable&lt;/td&gt;&lt;td&gt;Change au moindre changement dans le logiciel&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Dans &lt;a href="http://agilitateur.azeau.com/post/2012/03/06/Le-logiciel%2C-un-organisme-multicellulaire"&gt;un prochain billet&lt;/a&gt;, on parlera de la formation et de l'évolution de ces divers éléments.&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#rev-pnote-445-1" id="pnote-445-1"&gt;1&lt;/a&gt;] Apprenticeship Patterns "Reflect as you work" - &lt;a href="http://ofps.oreilly.com/titles/9780596518387/perpetual_learning.html#reflect_as_you_work"&gt;http://ofps.oreilly.com/titles/9780596518387/perpetual_learning.html#reflect_as_you_work&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#rev-pnote-445-2" id="pnote-445-2"&gt;2&lt;/a&gt;] Apprenticeship Patterns "Record what you learn" - &lt;a href="http://ofps.oreilly.com/titles/9780596518387/perpetual_learning.html#record_what_you_learn"&gt;http://ofps.oreilly.com/titles/9780596518387/perpetual_learning.html#record_what_you_learn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#rev-pnote-445-3" id="pnote-445-3"&gt;3&lt;/a&gt;] Apprenticeship Patterns "Share what you learn" - &lt;a href="http://ofps.oreilly.com/titles/9780596518387/perpetual_learning.html#share_what_you_learn"&gt;http://ofps.oreilly.com/titles/9780596518387/perpetual_learning.html#share_what_you_learn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#rev-pnote-445-4" id="pnote-445-4"&gt;4&lt;/a&gt;] Apprenticeship Patterns "Create feedback loops" - &lt;a href="http://ofps.oreilly.com/titles/9780596518387/perpetual_learning.html#create_feedback_loops"&gt;http://ofps.oreilly.com/titles/9780596518387/perpetual_learning.html#create_feedback_loops&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#rev-pnote-445-5" id="pnote-445-5"&gt;5&lt;/a&gt;] &lt;a href="http://www.academie-francaise.fr/dictionnaire/"&gt;http://www.academie-francaise.fr/dictionnaire/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#rev-pnote-445-6" id="pnote-445-6"&gt;6&lt;/a&gt;] &lt;a href="http://en.wikipedia.org/wiki/Domain_model"&gt;http://en.wikipedia.org/wiki/Domain_model&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#rev-pnote-445-7" id="pnote-445-7"&gt;7&lt;/a&gt;] &lt;a href="http://en.wikipedia.org/wiki/Interface_%28computing%29"&gt;http://en.wikipedia.org/wiki/Interface_%28computing%29&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#rev-pnote-445-8" id="pnote-445-8"&gt;8&lt;/a&gt;] &lt;a href="http://en.wikipedia.org/wiki/Lazy_evaluation"&gt;http://en.wikipedia.org/wiki/Lazy_evaluation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#rev-pnote-445-9" id="pnote-445-9"&gt;9&lt;/a&gt;] &lt;a href="http://en.wikipedia.org/wiki/Template_method_pattern"&gt;http://en.wikipedia.org/wiki/Template_method_pattern&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#rev-pnote-445-10" id="pnote-445-10"&gt;10&lt;/a&gt;] &lt;a href="http://www.objectmentor.com/resources/articles/granularity.pdf"&gt;http://www.objectmentor.com/resources/articles/granularity.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/03/05/#rev-pnote-445-11" id="pnote-445-11"&gt;11&lt;/a&gt;] &lt;a href="http://www.objectmentor.com/resources/articles/stability.pdf"&gt;http://www.objectmentor.com/resources/articles/stability.pdf&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/03/05/Conception-logicielle#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/03/05/Conception-logicielle#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/445</wfw:commentRss>
      </item>
    
  <item>
    <title>Je n'aime pas les conteneurs d'injection de dépendances</title>
    <link>http://agilitateur.azeau.com/post/2012/02/15/Je-n-aime-pas-les-conteneurs-d-injection-de-d%C3%A9pendances</link>
    <guid isPermaLink="false">urn:md5:a5303f0bc58c3ed0eca3b47402f85c56</guid>
    <pubDate>Wed, 15 Feb 2012 01:08:00 +0100</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
        <category>craftsmanship</category><category>csharp</category><category>DIP</category>    
    <description>    &lt;p&gt;Je n'ai rien contre les DI containers en tant que tels. Je pratique l'&lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;injection de dépendances&lt;/a&gt; aussi souvent que nécessaire mais j'ai un problème avec les librairies et frameworks en tout genre qui me donnent plus de &lt;a href="http://www.bonkersworld.net/programmers-only-shaving-who/"&gt;complications à gérer&lt;/a&gt; que d'écrire le code correspondant aux 10% de fonctionnalités dont j'ai réellement besoin.&lt;/p&gt;


&lt;p&gt;C'est pour cela que je lis avec grand plaisir des phrases telles que &lt;a href="https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert-martin/dependency-injection-inversion"&gt;"Dependency Injection doesn’t require a framework; it just requires that you invert your dependencies and then construct and pass your arguments to deeper layers"&lt;/a&gt; venant de quelqu'un dont la crédibilité n'est plus à démontrer.&lt;/p&gt;


&lt;p&gt;L'injection de dépendances, ce n'est jamais qu'un cas particulier de l'&lt;a href="http://en.wikipedia.org/wiki/Dependency_inversion_principle"&gt;inversion de dépendances&lt;/a&gt;, c'est à dire d'une structuration logicielle où les détails d'implémentation ne dépendent pas l'un de l'autre mais dépendent tous d'abstractions.&lt;br /&gt;
La spécificité de l'injection de dépendances, c'est, étant donnés un contexte et une abstraction, d'être capable de fournir automatiquement le détail d'implémentation de l'abstraction pour le contexte considéré. Bref, si on est capable d'implémenter l'appel suivant (écrit dans un pseudo langage objet), on est sur la bonne voie&amp;nbsp;:&lt;/p&gt;
&lt;pre&gt;
instance = context.GetDetailsFor(abstraction)
&lt;/pre&gt;


&lt;p&gt;Une abstraction, c'est typiquement ce que, dans les langages orientés objets les plus courants, on appelle une "interface", Mais un contexte&amp;nbsp;? J'ai un théorème pour répondre à ça.&lt;/p&gt;


&lt;p&gt;&lt;ins&gt;Théorème de oaz sur l'injection de dépendance&lt;/ins&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Le contexte d'une injection de dépendance peut se limiter à un choix de package&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&lt;ins&gt;Démonstration&lt;/ins&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Une abstraction étant fixée, une injection de dépendance est le choix d'une classe implémentant cette abstraction et des arguments de construction d'une instance de cette classe.&lt;br /&gt;
Les arguments de constructions peuvent être rendus optionnels&amp;nbsp;: il suffit pour cela d'utiliser une classe dérivée ad hoc où les arguments en question sont fixés.&lt;br /&gt;
Reste à choisir la classe à instancier.&lt;br /&gt;
Si une injection de dépendance nécessitait plus qu'un choix de package, cela signifierait que, en plus du package choisi, il faut d'autres informations qui permettent de choisir telle ou telle classe du package implémentant l'abstraction considérée. Cela implique que, parmi les classes du package choisi, au moins deux d'entre elles implémentent la même abstraction injectable et et ces deux ne vont donc pas être utilisées simultanément.&lt;br /&gt;
L'existence de ces deux classes dans le même package est une violation du &lt;a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod"&gt;Common Reuse Principle&lt;/a&gt; qui dit que "The classes in a package a reused together. If you reuse one of the classes in a package, you reuse them all"&lt;/p&gt;&lt;/blockquote&gt;


&lt;p&gt;&lt;br /&gt;
Ce résultat théorique n'est pas toujours pratique à mettre en oeuvre (du fait de la nécessité d'une classe dérivée dans certains cas) mais pour un grand nombre de cas d'injection de dépendances, il suffit amplement.&lt;br /&gt;&lt;/p&gt;


&lt;p&gt;Et, ce qui n'est pas pour me déplaire, dans un langage pas trop mal fichu, il me donne l'occasion d'écrire un "framework" basique d'injection de dépendances en 5 ou 6 lignes de code&amp;nbsp;:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
public static class MyDIContainer
{
  public static ABSTRACTION GetDetailsFor&amp;lt;ABSTRACTION&gt;(this Assembly a)
  {
      var candidates = a.GetTypes().Where(t =&gt; typeof(ABSTRACTION).IsAssignableFrom(t));
      if(candidates.Count() != 1)
        throw new ApplicationException(string.Format("Cannot find unique implementation of {0} in {1}", typeof(ABSTRACTION), a));
      return (ABSTRACTION) Activator.CreateInstance(candidates.First());
  }
}
&lt;/pre&gt;



&lt;p&gt;Ce "framework", qui se contente de retrouver dans un package donné l'unique classe qui implémente une interface donnée, s'utilise de la façon suivante&amp;nbsp;:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
var context = Assembly.LoadFile("DependenciesToInject.dll");
var instance = context.GetDetailsFor&amp;lt;IAmAnAbstraction&gt;();
&lt;/pre&gt;



&lt;p&gt;Une manière simple d'étendre ce "framework" pour prendre la main sur la phase de construction des instances, c'est de rajouter une interface "IProvideCustomDetails" et de l'implémenter dans les packages qui ont besoin de cette spécificité.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;
public interface IProvideCustomDetails
{
  ABSTRACTION GetDetailsFor&amp;lt;ABSTRACTION&gt;() where ABSTRACTION : class;
}

public static class MyDIContainer
{
  public static ABSTRACTION GetDetailsFor&amp;lt;ABSTRACTION&gt;(this Assembly a) where ABSTRACTION : class
  {
    return a.GetCustomDetailsFor&amp;lt;ABSTRACTION&gt;() ?? a.GetUniqueImplementationFor&amp;lt;ABSTRACTION&gt;();
  }
	
  public static ABSTRACTION GetUniqueImplementationFor&amp;lt;ABSTRACTION&gt;(this Assembly a) where ABSTRACTION : class
  {
    var candidates = a.GetTypes().Where(t =&gt; typeof(ABSTRACTION).IsAssignableFrom(t));
    if(candidates.Count() != 1)
      throw new ApplicationException(string.Format("Cannot find unique implementation of {0} in {1}", typeof(ABSTRACTION), a));
    return (ABSTRACTION) Activator.CreateInstance(candidates.First());
  }
	
  public static ABSTRACTION GetCustomDetailsFor&amp;lt;ABSTRACTION&gt;(this Assembly a) where ABSTRACTION : class
  {
    var provider = a.GetUniqueImplementationFor&amp;lt;IProvideCustomDetails&gt;();
    return ( provider == null ) ? null : provider.GetDetailsFor&amp;lt;ABSTRACTION&gt;();
  }
}
&lt;/pre&gt;



&lt;p&gt;Bien évidemment, ce genre de code ne va pas rendre l'intégralité des services que rendrait un conteneur de DI "prêt à l'emploi" mais, en ce qui me concerne, je n'ai pas besoin de beaucoup plus que ça (typiquement j'aurais tendance à rajouter un passage de données de configuration à l'appel GetDetailsFor).
Je n'ai donc aucune incitation pour utiliser des choses bien plus compliquées et qui nécessitent un suivi ne serait-ce que pour intégrer les mises à jour qui ne manquent pas de fleurir.&lt;/p&gt;


&lt;p&gt;Peut être que ce choix n'est finalement qu'une question de contexte de développement. Un développeur qui vogue de projet en projet aura tout intérêt à débarquer avec une panoplie de connaissances directement utilisables. La maîtrise d'un ou plusieurs DI container du marché en fait partie. Cela peut permettre de gagner du temps lors d'un démarrage de projet.&lt;br /&gt;
Mais un développeur qui passe des années à faire évoluer les mêmes produits, a-t-il le même intérêt ?&lt;br /&gt;
Gardons cela pour un autre débat...&lt;/p&gt;</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/02/15/Je-n-aime-pas-les-conteneurs-d-injection-de-d%C3%A9pendances#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/02/15/Je-n-aime-pas-les-conteneurs-d-injection-de-d%C3%A9pendances#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/425</wfw:commentRss>
      </item>
    
  <item>
    <title>Faut-il encore parler de méthodes agiles en 2012 ?</title>
    <link>http://agilitateur.azeau.com/post/2012/01/03/Faut-il-encore-parler-de-m%C3%A9thodes-agiles-en-2012</link>
    <guid isPermaLink="false">urn:md5:aba16540bcc6fbccc5748447f3006d91</guid>
    <pubDate>Tue, 03 Jan 2012 14:03:00 +0100</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
            
    <description>    &lt;p&gt;Les années passent et je me dis de plus en plus souvent&amp;nbsp;: mais pourquoi encore parler de méthodes &lt;em&gt;agiles&lt;/em&gt; ?&lt;br /&gt;
Pourquoi garder ce terme restrictif alors que l'on devrait, à mon avis, tout simplement parler de méthodes &lt;em&gt;professionnelles&lt;/em&gt; de développement logiciel&amp;nbsp;?&lt;/p&gt;


&lt;p&gt;Car c'est bien de cela dont il s'agit&amp;nbsp;: des valeurs, des principes et des pratiques qui guident toute activité de développement logiciel et qui caractérisent, sans fausse modestie ni dédain, le professionnalisme nécessaire à la satisfaction des utilisateurs et à la pérennité de l'ouvrage.&lt;/p&gt;


&lt;p&gt;En ce début d'année 2012, je ne vais donc prendre qu'une seule résolution pour toutes mes activités qui tournent autour du développement logiciel&amp;nbsp;: &lt;strong&gt;parler le moins possible de méthodes agiles et le plus possible de méthodes professionnelles&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;Et pour sortir du carcan des "méthodes agiles", quoi de mieux que de commencer l'année avec une rencontre axée sur l'écriture de code, activité majeure de tout développement logiciel ?&lt;br /&gt;
Le 5 janvier, c'est &lt;a href="http://antoine.vernois.net/dotclear/index.php?post/2012/01/02/Software-Craftsmanship-%C3%A0-Toulouse-5-janvier-2012"&gt;la première du software craftsmanship Toulouse&lt;/a&gt; (il y aurait aussi beaucoup à dire sur le terme craftsmanship mais chaque chose en son temps...)&lt;/p&gt;


&lt;p&gt;Dans mon agenda "agile", j'enchainerai les 2 et 3 février avec une &lt;a href="http://algec.iut-blagnac.fr/jagile/"&gt;réunion de sensibilisation aux méthodes agiles pour les enseignants des IUT Informatique&lt;/a&gt; où j'aurai le plaisir d'intervenir.&lt;br /&gt;
Malgré un programme pédagogique national des DUT informatique assez ancien, il y a des choses qu'un diplomé de 2012 qui se lance dans le développement logiciel devrait savoir et toute action de promotion/sensibilisation ne peut aller que dans le bon sens.&lt;br /&gt;
J'y animerai probablement un des ateliers ludiques sur &lt;a href="http://agilitateur.azeau.com/post/2011/08/25/Agile-Tour-Toulouse-2011-%3A-une-journ%C3%A9e-pour-les-d%C3%A9veloppeurs"&gt;l'importance des principes de conception pour garder un logiciel maintenable&lt;/a&gt; ou sur &lt;a href="http://agilitateur.azeau.com/post/2010/09/05/Stub-et-Mock-montent-sur-sc%C3%A8ne"&gt;la place des artefacts de test dans le TDD&lt;/a&gt;. Cela m'évitera de parler de méthodes agiles (ce que d'autres feront bien mieux que moi).&lt;/p&gt;


&lt;p&gt;Ce début d'année bien rempli se poursuivra &lt;a href="https://ticketlib.com/agileopensud"&gt;les 16 et 17 mars à Banyuls sur mer pour le premier Agile Open Sud&lt;/a&gt;. La rencontre entre une trentaine de passionnés&lt;sup&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/01/03/#pnote-443-1" id="rev-pnote-443-1"&gt;1&lt;/a&gt;]&lt;/sup&gt; promet d'être enrichissante.&lt;br /&gt;
J'y aborderai peut-être le sujet de la place des méthodes agiles. Sommes-nous contraints à vivre éternellement dans cet enclos pour bêtes curieuses du développement logiciel&amp;nbsp;? Est-ce aller trop loin que de suggérer le caractère non-professionnel de ceux qui resteraient scotchés sur des approches d'un autre siècle&amp;nbsp;?&lt;/p&gt;


&lt;p&gt;Mais mon principal chantier de l'année sera certainement de prendre du recul sur le chemin parcouru avec la même équipe de développement depuis six ans. Aujourd'hui, je n'utilise pas quotidiennement une méthode &lt;em&gt;agile&lt;/em&gt;. Je ne fais que développer une famille de produits logiciels en adaptant jour après jour la manière de travailler. Après avoir fait, il y trois ans, &lt;a href="http://agilitateur.azeau.com/post/2008/12/24/Videos-de-No%C3%ABl"&gt;un premier bilan sur la mise en place de Scrum&lt;/a&gt;, il me faudrait faire une synthèse sur tout ce qui a changé depuis&amp;nbsp;: &lt;a href="http://agilitateur.azeau.com/post/2011/04/05/Bye-Bye-Scrum"&gt;des itérations au flux&lt;/a&gt;, des estimations à la décomposition, des tests manuels aux tests automatisés et à l'exploration, l'architecture centrée sur le métier, l'apprentissage en continu...&lt;/p&gt;


&lt;p&gt;Je ne parlerai peut être plus de méthodes agiles mais je vais encore parler de développement logiciel pendant un certain temps.&lt;/p&gt;
&lt;div class="footnotes"&gt;&lt;h4&gt;Notes&lt;/h4&gt;
&lt;p&gt;[&lt;a href="http://agilitateur.azeau.com/post/2012/01/03/#rev-pnote-443-1" id="pnote-443-1"&gt;1&lt;/a&gt;] il reste encore des places mais ça devrait partir, je pense, assez vite&lt;/p&gt;&lt;/div&gt;
</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2012/01/03/Faut-il-encore-parler-de-m%C3%A9thodes-agiles-en-2012#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2012/01/03/Faut-il-encore-parler-de-m%C3%A9thodes-agiles-en-2012#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/443</wfw:commentRss>
      </item>
    
  <item>
    <title>Boucles à base de générateurs et de transformations : un exemple plus complet</title>
    <link>http://agilitateur.azeau.com/post/2011/12/24/Boucles-%C3%A0-base-de-g%C3%A9n%C3%A9rateurs-et-de-transformations-%3A-un-exemple-plus-complet</link>
    <guid isPermaLink="false">urn:md5:bf2ae6cb4b03bfa77c237d11584bfd51</guid>
    <pubDate>Sat, 24 Dec 2011 11:24:00 +0100</pubDate>
    <dc:creator>Oaz</dc:creator>
        <category>En français</category>
        <category>csharp</category><category>tdd</category>    
    <description>&lt;p&gt;Dans &lt;a href="http://agilitateur.azeau.com/post/2011/09/02/Faire-des-boucles-sans-%22while%22-ni-%22for%22-pour-les-rendre-plus-lisibles-et-maintenables"&gt;un billet précédent&lt;/a&gt;, j'avais évoqué une approche pour l'écriture de boucles permettant d'expliciter la combinaison de diverses exigences.&lt;br /&gt;
Le reproche fait dans les commentaires de ce billet est que cette approche serait moins lisible et rendrait inutilement le code plus compliqué.&lt;/p&gt;


&lt;p&gt;Pour ma part, je campe sur mes positions. L'approche n'est moins lisible que pour des exemples triviaux que l'on ne rencontre jamais dans un programme réel.&lt;br /&gt;
La complexité inhérente à ces programmes fait que, au final, un programme est plus facilement maintenu s'il se base sur une combinaison de générateurs et de transformations &lt;ins&gt;indépendantes&lt;/ins&gt; que s'il se base sur des boucles où tous les ingrédients sont mélangés.&lt;/p&gt;


&lt;p&gt;Ce débat me semble par ailleurs être une illustration de &lt;a href="http://www.infoq.com/presentations/Simple-Made-Easy" hreflang="en"&gt;la différence entre "simple" et "facile" mise en lumière par Rich Hickey&lt;/a&gt;. Les boucles while/for sont certainement plus &lt;ins&gt;faciles&lt;/ins&gt; à écrire au début mais elle ne donnent pas ce qu'il y a de plus &lt;ins&gt;simple&lt;/ins&gt; à maintenir et faire évoluer.&lt;/p&gt;


&lt;p&gt;Essayons donc de voir ce que cela donne avec un programme à peine plus riche que des exemples d'une ou deux lignes.&lt;/p&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;Soit un programme qui&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;demande à l'utilisateur de choisir une fonction parmi les suivantes&amp;nbsp;:
&lt;ul&gt;
&lt;li&gt;mettre un entier au carré&lt;/li&gt;
&lt;li&gt;calculer la somme des entiers inférieurs ou égaux à un entier donné&lt;/li&gt;
&lt;li&gt;calculer le k-ième terme de la suite de Syracuse à partir d'un entier donné, k étant un entier saisi par l'utilisateur&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;demande à l'utilisateur de choisir un filtre parmi les suivants&amp;nbsp;:
&lt;ul&gt;
&lt;li&gt;prendre les k premiers éléments, k étant un entier saisi par l'utilisateur&lt;/li&gt;
&lt;li&gt;prendre les éléments inférieurs ou égaux à k, k étant un entier saisi par l'utilisateur&lt;/li&gt;
&lt;li&gt;prendre les éléments impairs inférieurs ou égaux à k, k étant un entier saisi par l'utilisateur&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Lorsque l'utilisateur a fait ces choix, affiche les images par la fonction choisie précédemment des entiers naturels strictement positifs restreints au filtre lui aussi choisi précédemment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exemples d'utilisation&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;L'utilisateur choisit "mise au carré", puis "4 premiers éléments". Le programme affiche&amp;nbsp;: 1, 4, 9, 16&lt;/li&gt;
&lt;li&gt;L'utilisateur choisit "somme des entiers inférieurs ou égaux", puis "impairs inférieurs à 17". Le programme affiche&amp;nbsp;: 1, 3, 15&lt;/li&gt;
&lt;li&gt;L'utilisateur choisit "3ème terme de la suite de Syracuse", puis "éléments inférieurs à 6". Le programme affiche&amp;nbsp;: 2, 4, 5, 1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Voici une implémentation à base de générateurs et de transformations. &lt;a href="https://github.com/Oaz/NoLoop_Sample1"&gt;Le code complet est disponible sur github&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;J'ai essayé de décrire la démarche étape par étape mais je ne parle pas de ce qui a, dans le cas présent, un intérêt moindre, comme par exemple le découplage au niveau de l'"interface utilisateur" pour faciliter l'écriture des tests.&lt;/p&gt;


&lt;p&gt;Allons-y.&lt;/p&gt;    &lt;p&gt;J'écris un test pour le cas "mettre un entier au carré" + "prendre les k premiers éléments, k étant un entier saisi par l'utilisateur" et je ne me prends pas la tête pour son implémentation.&lt;/p&gt;
&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
[Test]
public void Compute_Square_For_FourFirstItems()
{
  var ui = new FakeUserInteraction(
    "square", "first items", "4"
  );
  Computer.Execute(ui);
  Assert.That (ui.DisplayedMessage,
    Is.EqualTo("1, 4, 9, 16"));
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public class Computer
{
  public static void Execute(ITalkToUser ui)
  {
    ui.Display("1, 4, 9, 16");
  }
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Je rajoute un test pour le même cas mais avec un k différent. Après une implémentation naïve, le refactoring m'amène à faire une boucle "for" sur le nombre d'éléments et à afficher et à calculer les carrés dans cette boucle.&lt;br /&gt;
Il est évident que, à cet instant, je n'ai pas un besoin impérieux de faire appel à d'autres concepts.&lt;/p&gt;
&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
[Test]
public void Compute_Square_For_FiveFirstItems()
{
  var ui = new FakeUserInteraction(
    "square", "first items", "5"
  );
  Computer.Execute(ui);
  Assert.That (ui.DisplayedMessage,
    Is.EqualTo("1, 4, 9, 16, 25"));
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public static void Execute(ITalkToUser ui)
{
  var dontCare = ui.Ask("choose operation");
  var dontCareAgain = ui.Ask("choose filter");
  var numberOfItems = int.Parse(ui.Ask("number of items"));
  var results = new List&amp;lt;int&gt;();
  for(var i=1; i &lt;= numberOfItems; i++)
    results.Add(i*i);
  ui.Display(string.Join(", ", results));
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Je rajoute un test pour le cas "mettre un entier au carré" + "prendre les éléments inférieurs ou égaux à k, k étant un entier saisi par l'utilisateur" et je commence par une implémentation naïve pour passer au vert.&lt;/p&gt;
&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
[Test]
public void Compute_Square_For_UnderTwenty()
{
  var ui = new FakeUserInteraction(
    "square", "under", "20"
  );
  Computer.Execute(ui);
  Assert.That (ui.DisplayedMessage,
    Is.EqualTo("1, 4, 9, 16"));
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public static void Execute(ITalkToUser ui)
{
  var dontCare = ui.Ask("choose operation");
  var filter = ui.Ask("choose filter");
  if( filter == "under" )
  {
    ui.Display("1, 4, 9, 16");
  }
  else
  {
    var numberOfItems = int.Parse(ui.Ask("number of items"));
    var results = new List&amp;lt;int&gt;();
    for(var i=1; i &lt;= numberOfItems; i++)
      results.Add(i*i);
    ui.Display(string.Join(", ", results));
  }
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Un premier refactoring m'amène à rendre similaires les deux cas&amp;nbsp;: ce sont tous les deux des boucles qui calculent des carrés&lt;/p&gt;
&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public static void Execute(ITalkToUser ui)
{
  var dontCare = ui.Ask("choose operation");
  var filter = ui.Ask("choose filter");
  var results = new List&amp;lt;int&gt;();
  if( filter == "under" )
  {
    var maxValue = int.Parse(ui.Ask("max value"));
    for(var i=1; i*i &lt;= maxValue; i++)
      results.Add(i*i);
  }
  else
  {
    var numberOfItems = int.Parse(ui.Ask("number of items"));
    for(var i=1; i &lt;= numberOfItems; i++)
      results.Add(i*i);
  }
  ui.Display(string.Join(", ", results));
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Un deuxième refactoring m'amène à extraire la fonction qui détermine le point d'arrêt de la boucle. On notera l'utilisation de lambda expressions avec fermeture pour capturer le paramètre k de la condition d'arrêt (soit un nombre d'éléments, soit une valeur maximale).&lt;br /&gt;
J'ai toujours ma boucle "for" mais je viens de réaliser une opération importante&amp;nbsp;: le choix de la condition d'arrêt est, dans sa totalité (incluant le dialogue utilisateur), externalisé dans une fonction "ChooseFilter".&lt;/p&gt;
&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public static void Execute(ITalkToUser ui)
{
  var dontCare = ui.Ask("choose operation");
  var results = new List&amp;lt;int&gt;();
  var untilConditionIsVerifiedFor = ChooseFilter(ui);
  for(var i=1; untilConditionIsVerifiedFor(i); i++)
    results.Add(i*i);
  ui.Display(string.Join(", ", results));
}

static Func&amp;lt;int,bool&gt; ChooseFilter(ITalkToUser ui)
{
  var filter = ui.Ask("choose filter");
  if( filter == "under" )
  {
    var maxValue = int.Parse(ui.Ask("max value"));
    return i =&gt; (i*i &lt;= maxValue);
  }
  else
  {
    var numberOfItems = int.Parse(ui.Ask("number of items"));
    return i =&gt; (i &lt;= numberOfItems);
  }
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Je rajoute un test pour le cas "calculer la somme des entiers inférieurs ou égaux à un entier donné" + "prendre les k premiers éléments, k étant un entier saisi par l'utilisateur".&lt;br /&gt;
Comme toujours, je commence par une implémentation qui me permet de rapidement passer au vert.&lt;/p&gt;

&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
[Test]
public void Compute_IntegerSum_For_FiveFirstItems()
{
  var ui = new FakeUserInteraction(
    "integer sum", "first items", "5"
  );
  Computer.Execute(ui);
  Assert.That (ui.DisplayedMessage,
    Is.EqualTo("1, 3, 6, 10, 15"));
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public static void Execute(ITalkToUser ui)
{
  var results = new List&amp;lt;int&gt;();
  var operation = ui.Ask("choose operation");
  if( operation == "integer sum" )
  {
    results.AddRange(new int[] {1,3,6,10,15});
  }
  else
  {
    var untilConditionIsVerifiedFor = ChooseFilter(ui);
    for(var i=1; untilConditionIsVerifiedFor(i); i++)
      results.Add(i*i);
  }
  ui.Display(string.Join(", ", results));
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Ensuite, toujours la même approche&amp;nbsp;: je rends les deux cas similaires. En l'occurrence, j'explicite la boucle de calcul des "sommes de n premiers entiers"&lt;/p&gt;
&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public static void Execute(ITalkToUser ui)
{
  var results = new List&amp;lt;int&gt;();
  var operation = ui.Ask("choose operation");
  if( operation == "integer sum" )
  {
    var untilConditionIsVerifiedFor = ChooseFilter(ui);
    for(var i=1; untilConditionIsVerifiedFor(i); i++)
      results.Add(i*(i+1)/2);
  }
  else
  {
    var untilConditionIsVerifiedFor = ChooseFilter(ui);
    for(var i=1; untilConditionIsVerifiedFor(i); i++)
      results.Add(i*i);
  }
  ui.Display(string.Join(", ", results));
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Pour terminer le refactoring, j'externalise le choix de l'opération.&lt;/p&gt;

&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public static void Execute(ITalkToUser ui)
{
  var results = new List&amp;lt;int&gt;();
  var operation = ChooseOperation(ui);
  var untilConditionIsVerifiedFor = ChooseFilter(ui);
  for(var i=1; untilConditionIsVerifiedFor(i); i++)
    results.Add(operation(i));
  ui.Display(string.Join(", ", results));
}

static Func&amp;lt;int,int&gt; ChooseOperation(ITalkToUser ui)
{
  var operation = ui.Ask("choose operation");
  if( operation == "integer sum" )
  {
    return i =&gt; i*(i+1)/2;
  }
  else
  {
    return i =&gt; i*i;
  }
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Je rajoute maintenant le cas de test "calculer la somme des entiers inférieurs ou égaux à un entier donné" + "prendre les éléments inférieurs ou égaux à k, k étant un entier saisi par l'utilisateur".&lt;br /&gt;
Une première implémentation m'amène à modifier le choix de la condition d'arrêt en y injectant l'opération réalisée.&lt;/p&gt;

&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
[Test]
public void Compute_IntegerSum_For_UnderTwelve()
{
  var ui = new FakeUserInteraction(
    "integer sum", "under", "12"
  );
  Computer.Execute(ui);
  Assert.That (ui.DisplayedMessage,
    Is.EqualTo("1, 3, 6, 10"));
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public static void Execute(ITalkToUser ui)
{
  var results = new List&amp;lt;int&gt;();
  var operation = ChooseOperation(ui);
  var untilConditionIsVerifiedFor = ChooseFilter(ui,operation);
  for(var i=1; untilConditionIsVerifiedFor(i); i++)
    results.Add(operation(i));
  ui.Display(string.Join(", ", results));
}

static Func&amp;lt;int,bool&gt;
ChooseFilter(ITalkToUser ui, Func&amp;lt;int,int&gt; operation)
{
  var filter = ui.Ask("choose filter");
  if( filter == "under" )
  {
    var maxValue = int.Parse(ui.Ask("max value"));
    return i =&gt; (operation(i) &lt;= maxValue);
  }
  else
  {
    var numberOfItems = int.Parse(ui.Ask("number of items"));
    return i =&gt; (i &lt;= numberOfItems);
  }
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Cela fonctionne mais me laisse insatisfait&amp;nbsp;: j'avais réussi à découpler le choix de la condition d'arrêt de l'opération et là j'ai dû réintroduire le couplage.&lt;br /&gt;
Pour corriger cela, il me faut sortir de la logique de la boucle "for". Je vais commencer par changer la structure de la boucle en introduisant un générateur de nombre entiers suivi d'un filtre (TakeWhile) et d'une projection (Select).&lt;/p&gt;

&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public static void Execute(ITalkToUser ui)
{
  var operation = ChooseOperation(ui);
  var conditionIsVerified = ChooseFilter(ui,operation);
  var results = Integers()
    .TakeWhile (conditionIsVerified)
    .Select (operation);
  ui.Display(string.Join(", ", results));
}

static IEnumerable&amp;lt;int&gt; Integers()
{
  int n = 1;
  while(true)
  {
    yield return n;
    n++;
  }
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Dans un deuxième temps, je change l'écriture de mon filtre&amp;nbsp;: plutôt que d'utiliser un TakeWhile avec une condition d'arrêt qui dépend du résultat de l'opération, je crée une fonction de filtrage qui dépend directement du choix utilisateur.&lt;/p&gt;

&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public static void Execute(ITalkToUser ui)
{
  var operation = ChooseOperation(ui);
  var results = Integers().Select(operation);
  var filteredResults = ChooseFilter(ui)(results);
  ui.Display(string.Join(", ", filteredResults));
}

static Func&amp;lt;IEnumerable&amp;lt;int&gt;,IEnumerable&amp;lt;int&gt;&gt;
  ChooseFilter(ITalkToUser ui)
{
  var filter = ui.Ask("choose filter");
  if( filter == "under" )
  {
    var maxValue = int.Parse(ui.Ask("max value"));
    return e =&gt; e.TakeWhile( n =&gt; n &lt;= maxValue);
  }
  else
  {
    var numberOfItems = int.Parse(ui.Ask("number of items"));
    return e =&gt; e.Take(numberOfItems);
  }
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;A ce stade de l'écriture de mon programme, où j'ai implémenté 2 types d'opérations et 2 types de filtres, j'ai réussi à séparer les divers concepts.&lt;br /&gt;
Je me retrouve donc avec quatre éléments indépendants&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;un générateur de nombre entiers&lt;/li&gt;
&lt;li&gt;la définition d'une opération en quelques lignes à partir d'éléments externes (un choix utilisateur)&lt;/li&gt;
&lt;li&gt;la définition d'un filtre en quelques lignes sur des entiers à partir d'autres éléments externes (un autre choix utilisateur)&lt;/li&gt;
&lt;li&gt;une fonction principale qui ne dépend pas directement des éléments externes et qui tient en 4 lignes tout en restant limpide&lt;/li&gt;
&lt;/ul&gt;
&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
public class Computer
{
  public static void Execute(ITalkToUser ui)
  {
    var operation = ChooseOperation(ui);
    var results = Integers().Select(operation);
    var filteredResults = ChooseFilter(ui)(results);
    ui.Display(string.Join(", ", filteredResults));
  }

  static IEnumerable&amp;lt;int&gt; Integers()
  {
    int n = 1;
    while(true)
    {
      yield return n;
      n++;
    }
  }

  static Func&amp;lt;int,int&gt; ChooseOperation(ITalkToUser ui)
  {
    var operation = ui.Ask("choose operation");
    if( operation == "integer sum" )
    {
      return i =&gt; i*(i+1)/2;
    }
    else
    {
      return i =&gt; i*i;
    }
  }

  static Func&amp;lt;IEnumerable&amp;lt;int&gt;,IEnumerable&amp;lt;int&gt;&gt; ChooseFilter(ITalkToUser ui)
  {
    var filter = ui.Ask("choose filter");
    if( filter == "under" )
    {
      var maxValue = int.Parse(ui.Ask("max value"));
      return e =&gt; e.TakeWhile( n =&gt; n &lt;= maxValue);
    }
    else
    {
      var numberOfItems = int.Parse(ui.Ask("number of items"));
      return e =&gt; e.Take(numberOfItems);
    }
  }
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;L'état où nous nous trouvons actuellement présente deux avantages (qui vont généralement de paire)&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;le code a une structure simple (éléments indépendants) qui reste facile à comprendre pour peu que l'on fasse l'effort d'apprendre des concepts qui vont au delà de l'écriture "classique" des boucles en programmation impérative.&lt;/li&gt;
&lt;li&gt;le code est maintenable&amp;nbsp;: on va pouvoir faire évoluer les éléments indépendants sans toucher aux autres. C'est ce que nous allons voir tout de suite.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Je rajoute un test pour le cas "calculer la somme des entiers inférieurs ou égaux à un entier donné" + "prendre les éléments impairs inférieurs ou égaux à k, k étant un entier saisi par l'utilisateur".&lt;br /&gt;
La nouveauté ici est le filtre sur les éléments impairs.&lt;br /&gt;
Sans surprise, il me suffit de modifier la définition du filtre en fonction des choix utilisateurs sans toucher aux autres parties du code.&lt;/p&gt;

&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
[Test]
public void
Compute_IntegerSum_For_OddUnderSeventeen()
{
  var ui = new FakeUserInteraction(
    "integer sum", "odd under", "17"
  );
  Computer.Execute(ui);
  Assert.That (ui.DisplayedMessage,
    Is.EqualTo("1, 3, 15"));
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
static Func&amp;lt;IEnumerable&amp;lt;int&gt;,IEnumerable&amp;lt;int&gt;&gt;
  ChooseFilter(ITalkToUser ui)
{
  var filter = ui.Ask("choose filter");
  if( filter == "odd under" )
  {
    var maxValue = int.Parse(ui.Ask("max value"));
    return e =&gt; e.TakeWhile( n =&gt; n &lt;= maxValue ).Where( n =&gt; n%2==1 );
  }
  else if( filter == "under" )
  {
    var maxValue = int.Parse(ui.Ask("max value"));
    return e =&gt; e.TakeWhile( n =&gt; n &lt;= maxValue );
  }
  else
  {
    var numberOfItems = int.Parse(ui.Ask("number of items"));
    return e =&gt; e.Take(numberOfItems);
  }
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;Si je veux rajouter une opération, même une qui ne soit pas triviale, pas de problème non plus&amp;nbsp;: je ne modifie que la partie "ChooseOperation".&lt;/p&gt;


&lt;p&gt;Je rajoute un test pour le cas "calculer le k-ième terme de la suite de Syracuse à partir d'un entier donné, k étant un entier saisi par l'utilisateur" + "prendre les éléments inférieurs ou égaux à k, k étant un entier saisi par l'utilisateur".&lt;/p&gt;

&lt;table border="1"&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
[Test]
public void
Compute_SyracuseThirdItem_For_UnderSix()
{
  var ui = new FakeUserInteraction(
    "syracuse", "3", "under", "6"
  );
  Computer.Execute(ui);
  Assert.That (ui.DisplayedMessage,
    Is.EqualTo("2, 4, 5, 1"));
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre class="brush: csharp; gutter: false;"&gt;
static Func&amp;lt;int,int&gt; ChooseOperation(ITalkToUser ui)
{
  var operation = ui.Ask("choose operation");
  if( operation == "syracuse" )
  {
    var rank = int.Parse(ui.Ask("rank"));
    return i =&gt; SyracuseSequence(i).ElementAt(rank-1);
  }
  else if( operation == "integer sum" )
  {
    return i =&gt; i*(i+1)/2;
  }
  else
  {
    return i =&gt; i*i;
  }
}

static IEnumerable&amp;ltint&gt; SyracuseSequence(int seed)
{
  var n = seed;
  while(true)
  {
    yield return n;
    if(n%2==0)
      n = n/2;
    else
      n = 3*n+1;
  }
}
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;



&lt;p&gt;J'espère avoir pu montrer que l'utilisation de générateurs et de diverses transformations (projections, filtres) pouvait avantageusement remplacer des boucles qui deviennent rapidement trop complexes dès que l'on est confronté à une variété de cas qui vont au delà du simple calcul et de la simple condition d'arrêt.&lt;/p&gt;


&lt;p&gt;Et je crois qu'il ne faut pas se bloquer sur quelques concepts qui peuvent paraitre, au début, trop complexes pour ce que l'on veut faire. On y gagne rapidement en lisibilité et maintenabilité et, avec l'habitude, cette façon d'écrire devient aussi naturelle que les structures de boucle plus connues.&lt;/p&gt;</description>
    
    
    
          <comments>http://agilitateur.azeau.com/post/2011/12/24/Boucles-%C3%A0-base-de-g%C3%A9n%C3%A9rateurs-et-de-transformations-%3A-un-exemple-plus-complet#comment-form</comments>
      <wfw:comment>http://agilitateur.azeau.com/post/2011/12/24/Boucles-%C3%A0-base-de-g%C3%A9n%C3%A9rateurs-et-de-transformations-%3A-un-exemple-plus-complet#comment-form</wfw:comment>
      <wfw:commentRss>http://feeds.feedburner.com/Agilitateur/comments/440</wfw:commentRss>
      </item>
    
</channel>
</rss>
