<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.infosaurus.fr/feed/rss2/xslt" ?><rss version="2.0"
  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">
<channel>
  <title>InfOsaurus</title>
  <link>http://blog.infosaurus.fr/</link>
  <atom:link href="http://blog.infosaurus.fr/feed/rss2" rel="self" type="application/rss+xml"/>
  <description></description>
  <language>fr</language>
  <pubDate>Tue, 31 Aug 2010 22:26:38 +0200</pubDate>
  <copyright></copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>FreakAngels</title>
    <link>http://blog.infosaurus.fr/post/2010/08/15/FreakAngels</link>
    <guid isPermaLink="false">urn:md5:172ad3231e3e76587ab089b719d9eefd</guid>
    <pubDate>Sun, 15 Aug 2010 15:29:00 +0200</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Bric-à-brac</category>
        <category>BD</category>    
    <description>    &lt;p&gt;Bon, c'est vrai qu'il est un peu tard pour les recommandations de livres
d'été. Mais je me devais de vous signaler une BD moyen format qui pourrait être
votre parfait compagnon sur la plage en cette fin de vacances (si vous avez la
chance d'en avoir) : FreakAngels.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/FreakAngelsCover.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.FreakAngelsCover_t.jpg&quot; alt=&quot;FreakAngels&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;(c) Editions du Lombard, 2010&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Le pitch :&lt;/p&gt;
&lt;p&gt;Londres, dans un futur pas si lointain. Une catastrophe sans précédent a
ravagé la ville, la submergeant en partie sous l'eau de mer. Dans le calme
post-apocalyptique du quartier de Whitechapel, les survivants se sont organisés
tant bien que mal mais le manque d'eau potable et de vivres se fait cruellement
ressentir.&lt;br /&gt;
&lt;br /&gt;
Heureusement, les FreakAngels veillent.&lt;br /&gt;
&lt;br /&gt;
Ces onze jeunes hommes et femmes aux étonnants pouvoirs télépathiques qui ont
organisé le ravitaillement et la défense du quartier sont la seule lueur
d'espoir de la population. Mais quels que soient leurs mérites, on comprend
très vite que ces anges ont aussi leur part d'ombre et des travers bien
humains, à commencer par Mark, le douzième membre renégat exilé dans le Nord.
Tout commence lorsqu'une jeune fille, Alice, est envoyée à WhiteChapel par Mark
pour abattre l'un des autres FreakAngels...&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/p15.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.p15_t.jpg&quot; alt=&quot;page15&quot; title=&quot;(c) www.freakangels.com&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/p16.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.p16_t.jpg&quot; alt=&quot;page16&quot; title=&quot;(c) www.freakangels.com&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/p17.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.p17_t.jpg&quot; alt=&quot;page17&quot; title=&quot;(c) www.freakangels.com&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/p18.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.p18_t.jpg&quot; alt=&quot;page18&quot; title=&quot;(c) www.freakangels.com&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
Réalisé par deux Anglais, &lt;a href=&quot;http://en.wikipedia.org/wiki/Warren_Ellis&quot; hreflang=&quot;en&quot;&gt;Warren Ellis&lt;/a&gt; et Paul Duffield, dont le style mêle manga
européen, comics et ligne claire, FreakAngels se déroule dans un monde de
&lt;em&gt;disaster fiction&lt;/em&gt; désabusé mais inventif, à l'image de ses habitants
qui doivent faire preuve d'ingéniosité pour survivre. Un peu comme dans la
classique BD &lt;a href=&quot;http://www.glenatbd.com/bd/neige-tome-01-9782723413848.htm&quot; hreflang=&quot;fr&quot;&gt;Neige&lt;/a&gt;, un petit groupe d'individus détient la clé du désastre qui a
frappé la région, et, qui sait, pourra peut-être réparer les dégâts.&lt;br /&gt;
Ce qui fait l'intérêt de FreakAngels, c'est que malgré les pouvoirs de
super-héros des personnages pricipaux, on est loin d'avoir affaire à des
sauveurs au-dessus de tout reproche. Les membres de la bande sont tour à tour
violents, paranoïaques, nymphomanes, parasitiques, névrosés, et passent une
bonne partie de leur temps en franches engueulades (dialogues savoureux signés
Ellis) avec des conséquences fâcheuses, pouvoirs psy obligent. Loin d'être
entièrement axé sur le paranormal, le comic fait la part belle à l'humanité des
personnages. Avec ou sans pouvoirs, ce sont avant tout de jeunes adultes paumés
qui tentent tant bien que mal d'assumer (ou pas) les responsabilités qui leur
incombent dans ce monde bouleversé.&lt;/p&gt;
&lt;p&gt;FreakAngels 1 est sorti il y a peu en français aux &lt;a href=&quot;http://www.lelombard.com/catalogue/Albums.cfm?AlbumID=7178&amp;amp;SerieID=4044&quot; hreflang=&quot;fr&quot;&gt;éditions du Lombard&lt;/a&gt; mais c'est à l'origine un webcomic
hebdomadaire gratuit proposé par les auteurs sur &lt;a href=&quot;http://www.freakangels.com&quot; hreflang=&quot;en&quot;&gt;www.freakangels.com&lt;/a&gt;. La VO est
donc disponible gratuitement jusqu'au tome 5... de quoi craquer en attendant le
deuxième livre en VF ;)&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2010/08/15/FreakAngels#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2010/08/15/FreakAngels#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/539687</wfw:commentRss>
      </item>
    
  <item>
    <title>Surplus cognitif et contraintes sociales</title>
    <link>http://blog.infosaurus.fr/post/2010/07/05/Surplus-cognitif-et-contraintes-sociales</link>
    <guid isPermaLink="false">urn:md5:f97fad4e81220d256eb825e32602c82a</guid>
    <pubDate>Mon, 05 Jul 2010 22:09:00 +0200</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Bric-à-brac</category>
        <category>Agile</category><category>Internet</category><category>TED</category>    
    <description>    &lt;p&gt;Je me balade souvent sur le site de &lt;a href=&quot;http://www.ted.com/&quot; hreflang=&quot;en&quot;&gt;la fondation TED&lt;/a&gt;, bien connue pour ses conférences. On y trouve des
vidéos de présentations très inspirantes sur des sujets comme les nouvelles
technologies, l'environnement, les sciences...&lt;/p&gt;
&lt;p&gt;Cette fois-ci, je suis tombé sur une intervention récente de Clay
Shirky : &amp;quot;How cognitive surplus will change the world&amp;quot;, que j'aimerais
vous faire partager :&lt;/p&gt;
&lt;div class=&quot;external-media&quot; style=&quot;margin: 1em auto; text-align: center;&quot;&gt;
&lt;object type=&quot;application/x-shockwave-flash&quot; data=&quot;http://blog.infosaurus.fr/?pf=player_flv.swf&quot; height=&quot;300&quot; width=&quot;400&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://blog.infosaurus.fr/?pf=player_flv.swf&quot; /&gt;
&lt;param name=&quot;wmode&quot; value=&quot;transparent&quot; /&gt;
&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot; /&gt;
&lt;param name=&quot;FlashVars&quot; value=&quot;margin=1&amp;amp;showvolume=1&amp;amp;showtime=1&amp;amp;showfullscreen=1&amp;amp;buttonovercolor=ff9900&amp;amp;slidercolor1=cccccc&amp;amp;slidercolor2=999999&amp;amp;sliderovercolor=0066cc&amp;amp;flv=http://video.ted.com/talks/dynamic/ClayShirky_2010S-medium.flv&amp;amp;width=400&amp;amp;height=300&quot; /&gt;&lt;/object&gt;&lt;br /&gt;

&lt;a href=&quot;http://video.ted.com/talks/dynamic/ClayShirky_2010S-medium.flv&quot;&gt;ClayShirky_2010S-medium.flv&lt;/a&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Quels enseignements peut-on tirer de ce que dit Shirky ?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;L'ère d'un peuple de &amp;quot;couch potatoes&amp;quot; vautrées devant la télé est sur le
déclin. Grâce à Internet et aux nouvelles technologies, la motivation dispose
d'un nouveau carburant, les initiatives sont permises et chacun devient capable
de créer et de partager - pour le meilleur et pour le pire.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Les contraintes contractuelles sont souvent bien moins efficaces que les
contraintes sociales. Les contraintes contractuelles peuvent paradoxalement
fausser le jeu en déculpabilisant les acteurs qui les subissent au détriment du
bien général de l'organisation, et ainsi déteriorer durablement la culture de
celle-ci.&lt;br /&gt;
&amp;quot;&lt;strong&gt;Social collaboration over contract negotiation&lt;/strong&gt;&amp;quot; en quelque
sorte... ça ne vous rappelle rien ? ;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;PS : j'ai aussi réalisé une version française de la vidéo, mais le
lecteur TED avec sous-titres ayant refusé de se laisser embedder, vous pouvez
la retrouver &lt;a href=&quot;http://www.ted.com/talks/lang/fre_fr/clay_shirky_how_cognitive_surplus_will_change_the_world.html&quot;&gt;
[ici]&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2010/07/05/Surplus-cognitif-et-contraintes-sociales#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2010/07/05/Surplus-cognitif-et-contraintes-sociales#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/531647</wfw:commentRss>
      </item>
    
  <item>
    <title>Persistez votre domaine avec Raven DB</title>
    <link>http://blog.infosaurus.fr/post/2010/06/02/Persister-son-domaine-avec-Raven-DB</link>
    <guid isPermaLink="false">urn:md5:88cd367d7685ed0de3b3573141110c29</guid>
    <pubDate>Wed, 02 Jun 2010 22:36:00 +0200</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Développement</category>
        <category>.NET</category><category>DDD</category><category>NoSQL</category>    
    <description>    &lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/Ravens.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.Ravens_s.jpg&quot; alt=&quot;Ravens&quot; style=&quot;float: left; margin: 0 1em 1em 0;&quot; title=&quot;Ravens&quot; /&gt;&lt;/a&gt;Il y a peu, je vous
parlais d'une &lt;a href=&quot;http://blog.infosaurus.fr/post/2010/03/05/R%C3%A8glement-de-comptes-%C3%A0-Donn%C3%A9es-Corral&quot; hreflang=&quot;fr&quot;&gt;possible synergie&lt;/a&gt; entre les bases de données NoSQL de type
document et les Agrégats de Domain Driven Design.&lt;/p&gt;
&lt;p&gt;Entretemps est sortie la base NoSQL pour la plateforme .NET d'Ayende Rahien,
&lt;a href=&quot;http://ravendb.net&quot; hreflang=&quot;en&quot;&gt;Raven DB&lt;/a&gt;, et elle confirme ces
suppositions. Voici un extrait de la documentation de la base au
corbeau :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;« When thinking about using Raven to persist entities, we need to consider
the two previous points. The suggested approach is to follow the Aggregate
pattern from the Domain Driven Design book. An Aggregate Root contains several
entities and value types and controls all access to the objects contained in
its boundaries. External references may only refer to the Aggregate Root, never
to one of its child objects.&lt;br /&gt;
When you apply this sort of thinking to a document database, there is a natural
and easy to follow correlation between an Aggregate Root (in DDD terms) and a
document in Raven. An Aggregate Root, and all the objects that it holds, is a
document in Raven. »&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Avec Raven, les données sont stockées dans des documents JSON qui
ressemblent à ça :&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/document_json.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.document_json_s.jpg&quot; alt=&quot;Document&quot; style=&quot;display: block; margin: 0 auto;&quot; title=&quot;Document&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Contrairement à une base relationnelle dans laquelle les données résident
dans des tables fragmentées qu'on peut relier par l'intégrité référentielle, il
est possible de stocker dans ce type de document tout un graphe d'objets
complexes et typés. Les préconisations pour la conception de documents Raven
sont donc à l'inverse de celles qui président au design d'une base de données
relationnelle : il s'agit de regrouper au sein d'un seul document les
objets formant un tout logique. Par exemple, un Livre regroupe à la fois un
titre mais aussi les objets que sont son Auteur et sa Catégorie. Il se trouve
que la notion d'Agrégat et de Racine d'Agrégat de DDD recoupe en tous points ce
concept.&lt;/p&gt;
&lt;p&gt;Un des bénéfices qu'on constate immédiatement avec Raven DB est
l'élimination pure et simple de la couche de mapping objet-relationnel, parfois
source de bien des complications. En effet avec Raven, plus de défaut
d'impédance entre les objets de l'application et leur équivalent persisté
relationnel. La couche persistance s'en trouve bien allégée.&lt;/p&gt;
&lt;br /&gt;
&lt;h3&gt;Exemple en C#&lt;/h3&gt;
&lt;p&gt;Comme un bon exemple vaut tous les discours, voici comment on peut
implémenter un Entrepôt avec Raven et son client C# natif :&lt;/p&gt;
&lt;br /&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Livre
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;    {
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Id { get; set; }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; Auteur Auteur { get; set; }
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Titre { get; set; }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; Categorie Categorie { get; set; }
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt;    }
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; EntrepotLivres
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;    {
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; EntrepotLivres(IDocumentSession documentSession)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;        {
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;            session = documentSession;
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;        }
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   8:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; AjouterLivre(Livre livre)
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   9:  &lt;/span&gt;        {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  10:  &lt;/span&gt;            session.Store(livre);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  11:  &lt;/span&gt;            session.SaveChanges();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  12:  &lt;/span&gt;        }
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  13:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  14:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; SupprimerLivre(Livre livre)
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  15:  &lt;/span&gt;        {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  16:  &lt;/span&gt;            session.Delete(livre);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  17:  &lt;/span&gt;            session.SaveChanges();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  18:  &lt;/span&gt;        }
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  19:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  20:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; Livre GetLivreParId(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; id)
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  21:  &lt;/span&gt;        {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  22:  &lt;/span&gt;            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; session.Load&amp;lt;Livre&amp;gt;(id);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  23:  &lt;/span&gt;        }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  24:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  25:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; IDocumentSession session;
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  26:  &lt;/span&gt;    }
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Program
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; Main(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt;[] args)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;    {
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;        var documentStore = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; DocumentStore { Url = &lt;span class=&quot;str&quot;&gt;&amp;quot;http://localhost:8080&amp;quot;&lt;/span&gt; };
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;        documentStore.Initialize();
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   8:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;using&lt;/span&gt; (var session = documentStore.OpenSession())
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   9:  &lt;/span&gt;        {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  10:  &lt;/span&gt;            EntrepotLivres entrepotLivres = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; EntrepotLivres(session);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  11:  &lt;/span&gt;            ...
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  12:  &lt;/span&gt;        }
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  13:  &lt;/span&gt;    }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  14:  &lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;p&gt;Pas de fichier de mapping à gérer à côté de ça, l'entité Livre et tout ce
qu'elle contient se persistera de façon immédiate... Simple, non ?&lt;/p&gt;
&lt;p&gt;On remarque qu'on manipule une Session Raven. Il s'agit d'une implémentation
du pattern &lt;a href=&quot;http://martinfowler.com/eaaCatalog/unitOfWork.html&quot; hreflang=&quot;en&quot;&gt;Unit of Work&lt;/a&gt; assez similaire à ce qu'on trouve dans des
frameworks d'ORM comme NHibernate. En fait, bon nombre de concepts et
dénominations dans l'API client C# de Raven sont directement issus de
NHibernate.&lt;/p&gt;
&lt;br /&gt;
&lt;h3&gt;Index et requêtes&lt;/h3&gt;
&lt;p&gt;Pour l'instant, notre Entrepôt ne fait qu'ajouter des entités, les supprimer
et les hydrater à partir de leur ID, ce qui se fait nativement avec Raven. Pour
exécuter des requêtes plus complexes sur nos documents, il faut passer par des
index. Les index sont des vues stockées sur disque semblables aux vues
matérialisées des SGBDR. Ils sont taillés pour un type de recherche
particulier.&lt;/p&gt;
&lt;p&gt;Voici comment on définit en C# un index qui porte sur les catégories des
livres :&lt;/p&gt;
&lt;br /&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;        documentStore.DatabaseCommands.PutIndex(&lt;span class=&quot;str&quot;&gt;&amp;quot;LivresParCategorie&amp;quot;&lt;/span&gt;, 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;            &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; IndexDefinition&amp;lt;Livre&amp;gt;
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;            {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;                Map = livres =&amp;gt; from livre &lt;span class=&quot;kwrd&quot;&gt;in&lt;/span&gt; livres
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;                                select &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; { livre.Categorie }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;            });
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;p&gt;Cet index ne doit être créé qu'une fois, il peut aussi être défini via
l'interface d'administration de Raven en utilisant la même syntaxe.&lt;/p&gt;
&lt;p&gt;On peut maintenant ajouter une méthode à notre entrepôt qui retourne tous
les livres d'une catégorie. Elle effectue une requête LuceneQuery sur l'index
précédemment défini :&lt;/p&gt;
&lt;br /&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; IList&amp;lt;Livre&amp;gt; GetLivresParCategorie(Categorie categorie)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;        {
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; session.LuceneQuery&amp;lt;Livre&amp;gt;(&lt;span class=&quot;str&quot;&gt;&amp;quot;LivresParCategorie&amp;quot;&lt;/span&gt;)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;                .Where(l =&amp;gt; l.Categorie == categorie)
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;                .ToList();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;        }
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;p&gt;Il existe une autre technique d'indexation plus sophistiquée, map/reduce,
dont je parlerai peut-être dans un autre billet.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/RavenDB.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.RavenDB_s.jpg&quot; alt=&quot;Raven DB&quot; style=&quot;display: block; margin: 0 auto;&quot; title=&quot;Raven DB&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Impressions&lt;/h3&gt;
&lt;p&gt;&lt;br /&gt;
&lt;strong&gt;Ce que j'aime dans Raven DB :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simplicité de persistance des objets et affranchissement complet de la
couche d'ORM.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Les données sont accessibles sous forme RESTful (chaque document dispose
d'une URL) et lisible par un humain.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Sans doute bien plus facilement scalable qu'un SGBDR du fait de la nature
atomique et autonome d'un document.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;API .NET et requêtage sur les indexes en Linq.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Raven se marie bien avec DDD et une partie de l'effort de design de la base
est déjà fait si on a découpé ses Agrégats.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Ce qui me plait moins :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pour exploiter pleinement Raven en termes de performances, il faut
idéalement ramener un seul document de la base et que celui-ci contienne tout
ce dont on a besoin. Cela peut mener à une tendance à calquer les documents sur
les IHM.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Raven DB a peut-être un petit impact sur la &lt;em&gt;persistance ignorance&lt;/em&gt;
de notre domaine. Il semble qu'une entité qui fait référence à la racine d'un
autre agrégat (donc située dans un autre document, en termes Raven) ne peut pas
avoir une référence directe à cet objet mais est obligé de contenir son ID à la
place. Dans notre exemple, l'Auteur d'un Livre est un objet entièrement contenu
dans l'agrégat Livre parce qu'on ne stocke que son nom et prénom. Mais si
l'Auteur devait faire l'objet d'un agrégat séparé à lui (par exemple si
l'auteur est un Utilisateur du système), le Livre devrait alors contenir la clé
de l'Auteur et plus l'Auteur lui même. Sachant que les IDs natifs de Raven sont
très typiques (&amp;quot;auteurs/465&amp;quot; par exemple), on se retrouve avec une trace de
Raven dans le graphe d'objets du domaine, et aussi la nécessité de passer par
un entrepôt pour réhydrater l'objet dont on n'a que la clé.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Les doutes à lever à l'avenir :&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Les performances. Ayende a publié des &lt;a href=&quot;http://ayende.com/Blog/archive/2010/04/24/raven-performance-testing.aspx&quot;&gt;mesures
de perfs&lt;/a&gt; prometteuses mais il va falloir qu'elles soient confirmées sur des
projets à plus grande échelle. En particulier, il serait intéressant de voir
comment le système de concurrence optimiste de Raven se comporte dans un
contexte transactionnel intensif.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;L'adoption. Je pense que les bases NoSQL ne survivront pas sans un
écosystème solide à la fois en termes de communauté et d'outillage disponible.
Si on ne peut pas faire avec les bases non relationnelles tout ce qu'on fait
avec les SGBDR (monitoring, tuning, reporting, analyse de données...), elles
resteront une bonne idée sur le papier mais un choix pauvre sur le
terrain.&lt;/li&gt;
&lt;/ul&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2010/06/02/Persister-son-domaine-avec-Raven-DB#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2010/06/02/Persister-son-domaine-avec-Raven-DB#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/524056</wfw:commentRss>
      </item>
    
  <item>
    <title>Bientôt l'été ! Quelques recettes pour faire mincir... ses TU</title>
    <link>http://blog.infosaurus.fr/post/2010/05/17/Bient%C3%B4t-l-%C3%A9t%C3%A9-%21-Quelquees-recettes-pour-faire-mincir...-ses-TU</link>
    <guid isPermaLink="false">urn:md5:87bdb506a5039024686681c764243ff8</guid>
    <pubDate>Mon, 17 May 2010 19:25:00 +0200</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Développement</category>
        <category>.NET</category><category>TDD</category><category>Tests</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/regime.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.regime_s.jpg&quot; alt=&quot;Régime&quot; style=&quot;display: block; margin: 0 auto;&quot; title=&quot;Régime&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;

&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  1:  &lt;/span&gt;[Test]
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  2:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; GetTousLivres_Retourne_Tous_Livres()
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  3:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  4:  &lt;/span&gt;    EntrepotLivres entrepotLivres = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; EntrepotLivres();
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  5:  &lt;/span&gt;    Auteur evans = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Auteur(&lt;span class=&quot;str&quot;&gt;&amp;quot;Evans&amp;quot;&lt;/span&gt;, &lt;span class=&quot;str&quot;&gt;&amp;quot;Eric&amp;quot;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  6:  &lt;/span&gt;    CategorieLivre categorie = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; CategorieLivre(&lt;span class=&quot;str&quot;&gt;&amp;quot;Développement&amp;quot;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  7:  &lt;/span&gt;    Adresse adresse = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Adresse(&lt;span class=&quot;str&quot;&gt;&amp;quot;55 rue des Pommiers&amp;quot;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  8:  &lt;/span&gt;    Librairie librairie = FabriqueLibrairie.Creer(&lt;span class=&quot;str&quot;&gt;&amp;quot;Librairie la Pomme d'Or&amp;quot;&lt;/span&gt;, adresse);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  9:  &lt;/span&gt;    IList&amp;lt;Librairie&amp;gt; librairies = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;Librairie&amp;gt;() { librairie };
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt; 10:  &lt;/span&gt;    Livre domainDrivenDesign = FabriqueLivre.Creer(&lt;span class=&quot;str&quot;&gt;&amp;quot;Domain Driven Design&amp;quot;&lt;/span&gt;, evans,
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt; 11:  &lt;/span&gt;        categorie, librairies);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt; 12:  &lt;/span&gt;    Livre autreLivre = FabriqueLivre.Creer(&lt;span class=&quot;str&quot;&gt;&amp;quot;autre livre&amp;quot;&lt;/span&gt;, evans, categorie, librairies);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt; 13:  &lt;/span&gt;    entrepotLivres.Ajouter(domainDrivenDesign);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt; 14:  &lt;/span&gt;    entrepotLivres.Ajouter(autreLivre);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt; 15:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt; 16:  &lt;/span&gt;    IList&amp;lt;Livre&amp;gt; livresRetournes = entrepotLivres.GetTousLivres();
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt; 17:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt; 18:  &lt;/span&gt;    Assert.AreEqual(2, livresRetournes.Count);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt; 19:  &lt;/span&gt;    Assert.Contains(domainDrivenDesign, livresRetournes);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt; 20:  &lt;/span&gt;    Assert.Contains(autreLivre, livresRetournes);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt; 21:  &lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Mais que fait donc ce test unitaire ?&lt;/p&gt;
&lt;p&gt;C'est la question que je me suis posée récemment en relisant un test du même
genre.&lt;/p&gt;
&lt;p&gt;Le titre peut nous donner une indication, mais le corps de ce test est
lui-même peu lisible. Et même sans rentrer dans le détail du code, il y a fort
à parier que la maintenabilité et la performance ne seront pas au rendez-vous
avec ce gros bloc d'initialisation (le Arrange de &lt;a href=&quot;http://agileinaflash.blogspot.com/2009/03/arrange-act-assert.html&quot; hreflang=&quot;en&quot;&gt;Arrange Act Assert&lt;/a&gt;) qui plombe le test.&lt;/p&gt;
&lt;p&gt;Le problème derrière tout ça, c'est que pour tester un comportement basique
d'un objet (ici un Repository de livres), on est obligé de le remplir en
initialisant toute une grappe d'autres objets (des livres, des auteurs,
catégories...) assez complexes à construire. DDD ne nous facilite pas vraiment
la tâche puisque si l'on veut assurer les invariants et garantir l'état valide
du domaine, le seul point d'accès pour créer un objet complexe est normalement
la Fabrique. Celle-ci va initialiser l'objet dans un état valide et demander
beaucoup de paramètres, dont potentiellement d'autres objets qui doivent être
construits eux aussi et... vous l'avez compris, le test devient rapidement
surchargé.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Respectons l'esprit de TDD&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Dans son livre XUnit Test Patterns et sur le site &lt;a href=&quot;http://xunitpatterns.com&quot; hreflang=&quot;en&quot;&gt;xunitpatterns.com&lt;/a&gt;, Gerard Meszaros
met un nom sur ce genre de code smell : &lt;a href=&quot;http://xunitpatterns.com/Obscure%20Test.html&quot; hreflang=&quot;en&quot;&gt;Obscure Test&lt;/a&gt;.
Il propose une approche de l'écriture de tests fidèle aux principes de TDD pour
éviter cet écueil :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;« Ecrire les tests d'une manière &amp;quot;outside-in&amp;quot; peut nous éviter de produire
des test obscurs qu'il faudrait ensuite refactorer. Dans cette approche, on
commence par tracer les contours d'un Test à 4 Phases en utilisant des appels à
des Méthodes Utilitaires de Tests non existantes.&lt;br /&gt;
Une fois qu'on est satisfait des tests, on peut commencer à écrire les méthodes
utilitaires dont on a besoin pour les exécuter. En écrivant les tests d'abord,
on obtient une meilleure compréhension de ce que les méthodes utilitaires
doivent nous apporter pour rendre l'écriture des tests aussi simple que
possible. »&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;En d'autres termes, on va créer le test le plus simple et le plus lisible
possible dès le départ en s'aidant de méthodes utilitaires très expressives.
Adieu la grappe d'objets, sa complexité sera cachée dans nos
méthodes :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  1:  &lt;/span&gt;[Test]
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  2:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; GetTousLivres_Retourne_Tous_Livres()
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  3:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  4:  &lt;/span&gt;    Livre domainDrivenDesign = CreerLivre(&lt;span class=&quot;str&quot;&gt;&amp;quot;Domain Driven Design&amp;quot;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  5:  &lt;/span&gt;    Livre autreLivre = CreerLivre(&lt;span class=&quot;str&quot;&gt;&amp;quot;Autre livre&amp;quot;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  6:  &lt;/span&gt;    EntrepotLivres entrepotLivres = CreerEntrepotAvecDeuxLivres(domainDrivenDesign,
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  7:  &lt;/span&gt;        autreLivre);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  8:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  9:  &lt;/span&gt;    List&amp;lt;Livre&amp;gt; livresRetournes = entrepotLivres.GetTousLivres();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt; 10:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt; 11:  &lt;/span&gt;    Assert.AreEqual(2, livresRetournes.Count);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt; 12:  &lt;/span&gt;    Assert.Contains(domainDrivenDesign, livresRetournes);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt; 13:  &lt;/span&gt;    Assert.Contains(autreLivre, livresRetournes);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt; 14:  &lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Et voici l'implémentation des méthodes utilitaires :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; Livre CreerLivre(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; titre)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;    Auteur auteur= &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Auteur(&lt;span class=&quot;str&quot;&gt;&amp;quot;Nom&amp;quot;&lt;/span&gt;, &lt;span class=&quot;str&quot;&gt;&amp;quot;Prénom&amp;quot;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;    CategorieLivre categorie = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; CategorieLivre(&lt;span class=&quot;str&quot;&gt;&amp;quot;Une catégorie&amp;quot;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;    Adresse adresse = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Adresse(&lt;span class=&quot;str&quot;&gt;&amp;quot;Une adresse&amp;quot;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;    Librairie librairie = FabriqueLibrairie.Creer(&lt;span class=&quot;str&quot;&gt;&amp;quot;Une librairie&amp;quot;&lt;/span&gt;, adresse);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt;    IList&amp;lt;Librairie&amp;gt; librairies = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;Librairie&amp;gt;() { librairie };
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   8:  &lt;/span&gt;    Livre livre = FabriqueLivre.Creer(titre, auteur, categorie, librairies);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   9:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; livre;
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  10:  &lt;/span&gt;}
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  11:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  12:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; EntrepotLivres CreerEntrepotAvecDeuxLivres(Livre livre1, Livre livre2)
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  13:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  14:  &lt;/span&gt;    EntrepotLivres entrepot = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; EntrepotLivres();
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  15:  &lt;/span&gt;    entrepot.Ajouter(livre1);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  16:  &lt;/span&gt;    entrepot.Ajouter(livre2);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  17:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; entrepot;
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  18:  &lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Coupons les cordons&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Notre test est déjà beaucoup plus lisible, mais une autre question se
profile à l'horizon. Est-il vraiment unitaire ? Peut-on dire qu'il est
atomique alors qu'il s'appuie intensivement sur le bon fonctionnement d'objets
externes, à savoir des Fabriques ?&lt;/p&gt;
&lt;p&gt;Meszaros préconise de s'affranchir des dépendances aux objets annexes en
recourant à des valeurs par défaut, ou en utilisant des &lt;a href=&quot;http://xunitpatterns.com/Dummy%20Object.html&quot; hreflang=&quot;en&quot;&gt;Dummy Objects&lt;/a&gt;,
des objets creux qui ne contiennent rien ou juste l'information nécessaire au
test. Concrètement, on extrait une interface du vrai objet en question pour
pouvoir créer des dummies sans contrainte de remplissage. Dans notre exemple
c'est le Livre qui sera &amp;quot;dummifié&amp;quot; puisque l'Entrepot à tester contient
directement des Livres :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;interface&lt;/span&gt; ILivre
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;    ...
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;}
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; DummyLivre : ILivre
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   8:  &lt;/span&gt;    &lt;span class=&quot;rem&quot;&gt;//On construit un objet minimal&lt;/span&gt;
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   9:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; DummyLivre(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; titre)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  10:  &lt;/span&gt;    {
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  11:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.titre = titre;
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  12:  &lt;/span&gt;    }
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  13:  &lt;/span&gt;}
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  14:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  15:  &lt;/span&gt;&lt;span class=&quot;rem&quot;&gt;//Nouvelle méthode du helper&lt;/span&gt;
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  16:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; DummyLivre CreerLivre(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; titre)
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  17:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  18:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; DummyLivre(titre);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  19:  &lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Cette solution ne me satisfait pas pleinement parce qu'il faut créer un
interface ILivre et la faire implémenter à Livre, ce qui n'est pas forcément
élégant au regard de la nécessité d'expressivité des classes du domaine dans
DDD. A la place, on peut recourir à un framework d'isolation qui va instancier
un proxy de notre Livre pour l'utiliser dans les tests sans besoin de recourir
à une interface. Un exemple avec Moq :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;protected&lt;/span&gt; Livre CreerLivre(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; titre)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;    var mockLivre = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Mock&amp;lt;Livre&amp;gt;();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;    mockLivre.Setup(livre =&amp;gt; livre.Titre).Returns(titre);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; mockLivre.Object;
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;NB : cela nécessite une petite modification de la classe Livre. Il faut
rendre la property Titre &lt;em&gt;virtual&lt;/em&gt; afin que Moq puisse la
surcharger.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Stratégies d'extraction&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Tout cela est très bien, mais nous avons toujours des méthodes utilitaires à
l'intérieur de notre classe de test, ce qui n'est pas l'idéal pour la
lisibilité et la réutilisabilité. Une solution pourrait être de rendre ces
méthodes statiques et de les externaliser dans un Helper à part (on parle aussi
de pattern &lt;a href=&quot;http://www.c2.com/cgi/wiki?ObjectMother&quot; hreflang=&quot;en&quot;&gt;ObjectMother&lt;/a&gt;) :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  1:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; LivreTestHelper
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  2:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  3:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; Livre CreerLivre(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; titre) { ... }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  4:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;static&lt;/span&gt; EntrepotLivres CreerEntrepotAvecDeuxLivres(Livre livre1,
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  5:  &lt;/span&gt;        Livre livre2) { ... }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  6:  &lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Voici maintenant à quoi ressemble le test :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  1:  &lt;/span&gt;[Test]
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  2:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; GetTousLivres_Retourne_Tous_Livres()
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  3:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  4:  &lt;/span&gt;    Livre domainDrivenDesign = LivreTestHelper.CreerLivre(&lt;span class=&quot;str&quot;&gt;&amp;quot;Domain Driven Design&amp;quot;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  5:  &lt;/span&gt;    Livre autreLivre = LivreTestHelper.CreerLivre(&lt;span class=&quot;str&quot;&gt;&amp;quot;Autre livre&amp;quot;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  6:  &lt;/span&gt;    EntrepotLivres entrepotLivres = LivreTestHelper.CreerEntrepotAvecDeuxLivres(
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  7:  &lt;/span&gt;        domainDrivenDesign, autreLivre);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  8:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  9:  &lt;/span&gt;    IList&amp;lt;Livre&amp;gt; livresRetournes = entrepotLivres.GetTousLivres();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt; 10:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt; 11:  &lt;/span&gt;    Assert.AreEqual(2, livresRetournes.Count);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt; 12:  &lt;/span&gt;    Assert.Contains(domainDrivenDesign, livresRetournes);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt; 13:  &lt;/span&gt;    Assert.Contains(autreLivre, livresRetournes);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt; 14:  &lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Imaginons maintenant qu'on ait d'autres tests à écrire sur l'EntrepotLivres.
Chacun va avoir besoin de son contexte d'initialisation particulier (livres
avec une certaine catégorie, un certain auteur, un nombre de livres fixé...)
Chaque test va ajouter ses méthodes au TestHelper et il y a fort à parier qu'on
va vite se retrouver avec un helper obèse et beaucoup de duplication de code,
chaque test ayant besoin d'un environnement légèrement différent des autres
mais avec des choses communes.&lt;/p&gt;
&lt;p&gt;C'est là que nous pouvons appeler le pattern &lt;a href=&quot;http://www.natpryce.com/articles/000714.html&quot; hreflang=&quot;en&quot;&gt;Test Data
Builder&lt;/a&gt; à la rescousse. Il va nous permettre de rendre modulaire la
construction de notre contexte de test, sans trop nuire à la lisibilité.&lt;/p&gt;
&lt;p&gt;Voici à quoi pourrait ressembler un test avec des DataBuilder :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;[Test]
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; GetLivresParNomAuteur_Retourne_Bons_Livres()
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;    Livre domainDrivenDesign = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; LivreBuilder()
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;        .AvecTitre(&lt;span class=&quot;str&quot;&gt;&amp;quot;Domain Driven Design&amp;quot;&lt;/span&gt;)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;        .AvecAuteur(&lt;span class=&quot;str&quot;&gt;&amp;quot;Eric&amp;quot;&lt;/span&gt;,  &lt;span class=&quot;str&quot;&gt;&amp;quot;Evans&amp;quot;&lt;/span&gt;)
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt;        .Creer();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   8:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   9:  &lt;/span&gt;    Livre autreLivre = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; LivreBuilder()
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  10:  &lt;/span&gt;        .AvecTitre(&lt;span class=&quot;str&quot;&gt;&amp;quot;Autre titre&amp;quot;&lt;/span&gt;)
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  11:  &lt;/span&gt;        .AvecAuteur(&lt;span class=&quot;str&quot;&gt;&amp;quot;Autre&amp;quot;&lt;/span&gt;, &lt;span class=&quot;str&quot;&gt;&amp;quot;Auteur&amp;quot;&lt;/span&gt;)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  12:  &lt;/span&gt;        .Creer();
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  13:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  14:  &lt;/span&gt;    EntrepotLivres entrepotLivres = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; EntrepotLivresBuilder()
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  15:  &lt;/span&gt;        .AvecLivre(domainDrivenDesign)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  16:  &lt;/span&gt;        .AvecLivre(autreLivre)
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  17:  &lt;/span&gt;        .Creer();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  18:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  19:  &lt;/span&gt;    List&amp;lt;Livre&amp;gt; livresRetournes = entrepotLivres.GetLivresParNomAuteur(&lt;span class=&quot;str&quot;&gt;&amp;quot;Evans&amp;quot;&lt;/span&gt;);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  20:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  21:  &lt;/span&gt;    Assert.AreEqual(1, livresRetournes.Count);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  22:  &lt;/span&gt;    Assert.Contains(domainDrivenDesign, livresRetournes);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  23:  &lt;/span&gt;    Assert.IsFalse(livresRetournes.Contains(autreLivre));
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  24:  &lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Je ne sais pas ce que vous en pensez, mais je trouve ça plutôt agréable à
l'oeil. Sous le capot, cela donne ça :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; LivreBuilder
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;    Mock&amp;lt;Livre&amp;gt; mockLivre = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Mock&amp;lt;Livre&amp;gt;();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;   &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; LivreBuilder AvecTitre(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; titre)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;    {
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt;        mockLivre.Setup(livre =&amp;gt; livre.Titre).Returns(titre);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   8:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;;
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   9:  &lt;/span&gt;    }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  10:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  11:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; LivreBuilder AvecAuteur(&lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; prenomAuteur, &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; nomAuteur)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  12:  &lt;/span&gt;    {
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  13:  &lt;/span&gt;        var mockAuteur = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Mock&amp;lt;Auteur&amp;gt;();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  14:  &lt;/span&gt;        mockAuteur.Setup(au =&amp;gt; au.Prenom).Returns(prenomAuteur);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  15:  &lt;/span&gt;        mockAuteur.Setup(au =&amp;gt; au.Nom).Returns(nomAuteur);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  16:  &lt;/span&gt;        mockLivre.Setup(livre =&amp;gt; livre.Auteur).Returns(mockAuteur.Object);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  17:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;;
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  18:  &lt;/span&gt;    }
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  19:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  20:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; Livre Creer()
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  21:  &lt;/span&gt;    {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  22:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; mockLivre.Object;
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  23:  &lt;/span&gt;    }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  24:  &lt;/span&gt;}
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  25:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  26:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; EntrepotLivresBuilder
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  27:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  28:  &lt;/span&gt;    EntrepotLivres entrepotLivres = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; EntrepotLivres();
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  29:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  30:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; EntrepotLivresBuilder AvecLivre(Livre livre)
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  31:  &lt;/span&gt;    {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  32:  &lt;/span&gt;        entrepotLivres.Ajouter(livre);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  33:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;;
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  34:  &lt;/span&gt;    }
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  35:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  36:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; EntrepotLivres Creer()
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  37:  &lt;/span&gt;    {
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  38:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; entrepotLivres;
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  39:  &lt;/span&gt;    }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  40:  &lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Un mot sur SetUp&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;On pourrait aussi être tenté d'instancier une partie du contexte des tests
dans la méthode de SetUp de la classe de test (attribut [SetUp] avec
NUnit).&lt;/p&gt;
&lt;p&gt;Ce n'est pas forcément l'idéal en termes de lisibilité, et en tout cas on ne
devrait construire dans cette méthode que les données qui sont le plus petit
dénominateur commun entre tous les tests. En général, je préfère réserver le
SetUp (et le TearDown) pour des opérations de plomberie générale des tests qui
ne touchent pas au données, comme le démarrage et le rollback d'une
transaction.&lt;/p&gt;
&lt;p&gt;Dans ce sens, je suis assez d'accord avec Roy Osherove, auteur de &lt;em&gt;The
Art Of Unit Testing&lt;/em&gt;, qui écrit (p. 191) :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;« Ma préférence personnelle est que chaque test crée ses propres mocks et
stubs en appelant des méthodes de helpers dans le test lui-même, de façon à ce
que le lecteur du test sache exactement ce qui se passe, sans avoir besoin de
sauter du test au setup pour comprendre le tableau d'ensemble. »&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/674101_78133251.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.674101_78133251_s.jpg&quot; alt=&quot;Recette&quot; style=&quot;display: block; margin: 0 auto;&quot; title=&quot;Recette&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Une alternative originale&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Le Danois Mark Seemann propose une approche légèrement différente, qui fait
partie d'un cortège de design patterns et conventions qu'il a appelé &lt;a href=&quot;http://blog.ploeh.dk/2009/01/28/ZeroFrictionTDD.aspx&quot; hreflang=&quot;en&quot;&gt;ZeroFriction TDD&lt;/a&gt;. Bien que je ne sois pas totalement persuadé par tous
les patterns présentés (certains sont très orientés programmation défensive),
un d'entre eux mérite qu'on s'y attarde : &lt;a href=&quot;http://blog.ploeh.dk/2009/03/16/FixtureObject.aspx&quot; hreflang=&quot;en&quot;&gt;Fixture
Object&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Seemann part du constat qu'en utilisant des helpers de tests statiques, on a
forcément un contexte de test &lt;em&gt;stateless&lt;/em&gt;, ce qui nous prive de
certaines commodités. L'idée est de constituer un objet Fixture contenant
l'état actuel des données de test et aussi la référence au système à tester
(SUT). Ainsi le corps du test garde sa lisibilité et sa
maintenabilité :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;[Test]
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; GetTousLivres_Retourne_Tous_Livres()
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;    EntrepotLivresFixture fixture = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; EntrepotLivresFixture();
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;    fixture.AjouterPlusieursLivres();
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   8:  &lt;/span&gt;    &lt;span class=&quot;rem&quot;&gt;// System Under Test&lt;/span&gt;
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   9:  &lt;/span&gt;    EntrepotLivres sut = fixture.Sut;
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  10:  &lt;/span&gt;    List&amp;lt;Livre&amp;gt; resultats = sut.GetTousLivres();
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  11:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  12:  &lt;/span&gt;    Assert.AreEqual(fixture.Livres, resultats);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  13:  &lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;On remarque que deux conventions de Zero Friction TDD censées reposer l'oeil
et le cerveau du lecteur du test sont utilisées : &lt;a href=&quot;http://blogs.msdn.com/ploeh/archive/2008/10/06/naming-sut-test-variables.aspx&quot; hreflang=&quot;en&quot;&gt;Naming SUT Test Variables&lt;/a&gt;, qui préconise de nommer toujours
de la même manière la variable de l'objet testé, et &lt;a href=&quot;http://blogs.msdn.com/ploeh/archive/2008/11/14/naming-direct-output-variables.aspx&quot; hreflang=&quot;en&quot;&gt;Naming Direct Output Variables&lt;/a&gt;, qui conseille la même chose
pour le résultat qui va être asserté.&lt;/p&gt;
&lt;p&gt;Voici l'implémentation du Fixture Object :&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div class=&quot;csharpcode&quot;&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   1:  &lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; EntrepotLivresFixture
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   2:  &lt;/span&gt;{
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   3:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; EntrepotLivresFixture()
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   4:  &lt;/span&gt;    {
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   5:  &lt;/span&gt;        Sut = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; EntrepotLivres();
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   6:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.Livres = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; List&amp;lt;Livre&amp;gt;();
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   7:  &lt;/span&gt;    }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;   8:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;   9:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; EntrepotLivres Sut { get; &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; set; }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  10:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; IList&amp;lt;Livre&amp;gt; Livres { get; &lt;span class=&quot;kwrd&quot;&gt;private&lt;/span&gt; set; }
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  11:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; Plusieurs { get { &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; 3; } }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  12:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; Livre PremierLivre { get { &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; Livres[0]; } }
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  13:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; Livre DeuxiemeLivre { get { &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; Livres[1]; } }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  14:  &lt;/span&gt; 
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  15:  &lt;/span&gt;    &lt;span class=&quot;kwrd&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; AjouterPlusieursLivres()
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  16:  &lt;/span&gt;    {
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  17:  &lt;/span&gt;        &lt;span class=&quot;kwrd&quot;&gt;for&lt;/span&gt; (&lt;span class=&quot;kwrd&quot;&gt;int&lt;/span&gt; i = 0; i &amp;lt; Plusieurs; i++)
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  18:  &lt;/span&gt;        {
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  19:  &lt;/span&gt;            Livre livre = &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Mock&amp;lt;Livre&amp;gt;().Object;
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  20:  &lt;/span&gt;            Livres.Add(livre);
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  21:  &lt;/span&gt;            Sut.Ajouter(livre);
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  22:  &lt;/span&gt;        }
&lt;/pre&gt;
&lt;pre class=&quot;alt&quot;&gt;
&lt;span class=&quot;lnum&quot;&gt;  23:  &lt;/span&gt;    }
&lt;/pre&gt;
&lt;pre&gt;
&lt;span class=&quot;lnum&quot;&gt;  24:  &lt;/span&gt;}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;Voilà, ceci n'est qu'un échantillon des différentes stratégies de
factorisation de tests imaginables. Il y a probablement des milliers de
solutions possibles.&lt;/p&gt;
&lt;p&gt;Et vous, quelle est votre régime minceur préféré pour vos tests ?&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2010/05/17/Bient%C3%B4t-l-%C3%A9t%C3%A9-%21-Quelquees-recettes-pour-faire-mincir...-ses-TU#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2010/05/17/Bient%C3%B4t-l-%C3%A9t%C3%A9-%21-Quelquees-recettes-pour-faire-mincir...-ses-TU#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/517538</wfw:commentRss>
      </item>
    
  <item>
    <title>Règlement de comptes à Données Corral</title>
    <link>http://blog.infosaurus.fr/post/2010/03/05/R%C3%A8glement-de-comptes-%C3%A0-Donn%C3%A9es-Corral</link>
    <guid isPermaLink="false">urn:md5:eb15207207087721d46aca2f501aba8e</guid>
    <pubDate>Fri, 05 Mar 2010 19:50:00 +0100</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Développement</category>
        <category>Bases de données</category><category>DDD</category><category>NoSQL</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/tombstone-1993-11-g.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.tombstone-1993-11-g_s.jpg&quot; alt=&quot;Il va y avoir du sport&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Il va y avoir du sport&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Derrière le jeu de mots vaseux de ce titre se cache une réalité beaucoup
moins fun. Celle de la guerre que se livrent, depuis quelques temps déjà, les
partisans d'une approche des bases de données novatrice et iconoclaste et les
défenseurs de la tradition des SGBD relationnels.&lt;/p&gt;
&lt;p&gt;Si vous suivez l'actualité du monde du développement, vous avez déjà compris
de quoi je veux parler. Il ne vous a pas échappé que ces derniers temps,
l'hégémonie des systèmes relationnels sur le marché des bases de données a été
quelque peu chahutée : en 2009 sont apparues un certain nombre de bases
regroupées sous le nom parapluie de &amp;quot;NoSQL&amp;quot;. Ces systèmes (CouchDB, Big Table
de Google, Project Voldemort...) sont des key-value stores, des document stores
ou des bases fondées sur les graphes qui ont en commun de partir d'un constat
de lourdeur du relationnel, du langage SQL et de ses jointures. Elles se
veulent plus simples d'approche, plus &lt;em&gt;scalable&lt;/em&gt; pour de gros volumes de
données, plus adaptées au web et moins sclérosées par les schémas de
données.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;La rébellion gagne des voix&lt;/h3&gt;
&lt;p&gt;Il est intéressant de voir qu'en ce début d'année, il y a un regain de
tension dans le débat qui oppose les deux visions et que celui-ci s'est invité
chez les développeurs .NET. Plus particulièrement, deux acteurs importants de
la communauté et qui n'ont pas a priori d'intérêt particulier à soutenir les
bases NoSQL, ont pris position pour les défendre.&lt;/p&gt;
&lt;p&gt;Le premier est Ayende Rahien, contributeur du projet NHibernate et créateur
entre autres du framework d'isolation RhinoMocks. Dans un article nommé
&lt;a href=&quot;http://ayende.com/Blog/archive/2010/02/22/slaying-relational-dragons.aspx&quot; hreflang=&quot;en&quot;&gt;Slaying Relational Dragons&lt;/a&gt;, il remet en cause l'hégémonie des
SGBDR et cite une session de support client à l'issue de laquelle il a
recommandé de ne pas utiliser de base relationnelle. S'en suit un exemple de
type d'application pour laquelle selon lui, il est tout à fait justifié d'opter
pour un document store du style CouchDB. Plus étonnant, Ayende a également
démarré un projet de base document, Rhino DivanDB, alors même qu'une grande
partie de son travail des dernières années a été dévoué indirectement aux bases
relationnelles par le biais d'NHibernate.&lt;/p&gt;
&lt;p&gt;Une autre chose a piqué ma curiosité dans le billet d'Ayende : pour
décrire les grappes de données pêchées dans une base NoSQL, il utilise le terme
d'Agrégats. Oui, c'est à peu près la même notion d'Agrégat que dans Domain
Driven Design. Visuellement, cela peut donner ceci (2 racines d'agrégat Book en
l'occurrence) :&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/image_16.png&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.image_16_s.jpg&quot; alt=&quot;Agrégats&quot; title=&quot;Agrégats&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si on cherche un peu, on s'aperçoit aussi que des frameworks DDD comme
&lt;a href=&quot;http://www.slideshare.net/banq/ddd-framework-for-java-jdonframework-2881760&quot; hreflang=&quot;en&quot;&gt;Jdon&lt;/a&gt; prévoient d'entrée l'utilisation d'une base NoSQL pour
la persistance. Y aurait-il une synergie entre DDD et NoSQL dans la forme sous
laquelle les entités sont appréhendées ? Intéressant, à creuser en tout
cas.&lt;/p&gt;
&lt;p&gt;Notre deuxième homme est Greg Young, très impliqué dans DDD justement, et
qui a popularisé l'approche Command-Query Separation. Greg a comparé dans un
billet récent l'utilisation d'un ORM au fait d'&lt;a href=&quot;http://codebetter.com/blogs/gregyoung/archive/2010/02/18/using-an-orm-is-like-kissing-your-sister.aspx&quot; hreflang=&quot;en&quot;&gt;embrasser sa soeur&lt;/a&gt; (expression américaine désignant une
action dénuée d'intérêt)... Pour lui, nous devrions plus souvent nous arrêter
et nous demander si le choix d'un ORM couplé à un modèle de données relationnel
pour notre projet, est bien justifié. Plutôt que de faire de l'ORM + SGBDR le
choix par défaut, pourquoi ne pas envisager une base objet ou une base document
à la place ? Dans certains cas, c'est beaucoup plus adapté au contexte et
ça évite les problèmes de décalage d'impédance entre l'application objet et le
modèle de données.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;L'Empire contre-attaque&lt;/h3&gt;
&lt;p&gt;Bien sûr, les défenseurs des SGBD relationnels ont tôt fait de réagir. Un
des plus virulents dans la contre-offensive a certainement été Frans Bouma,
curieusement acteur de la scène ORM lui aussi (avec LLBLGen). Dans des
commentaires et &lt;a href=&quot;http://weblogs.asp.net/fbouma/archive/2010/02/24/database-theory-your-friend-for-success.aspx&quot; hreflang=&quot;en&quot;&gt;sur son blog&lt;/a&gt;, il avance trois arguments principaux pour
contrer les enthousiastes du NoSQL :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Les cas évoqués par Ayende sont des anti-pattern, on essaie de créer un
modèle de données qui est directement calqué sur la mise en forme d'un écran de
l'application, ce qui est une mauvaise pratique.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Un modèle de données a pour vocation de représenter la &lt;em&gt;réalité&lt;/em&gt;, et
pas juste de refléter des entités utilisées dans une application (on retrouve
un peu ici l'approche bottom-up vs l'approche top-down). Pourquoi ? Parce
que dans un contexte d'entreprise, de multiples logiciels accèdent aux mêmes
données et c'est de plus en plus vrai au fil du temps. Il faut donc un modèle
qui représente parfaitement le métier et en est le garant quelle que soit
l'application qui y puisera.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Les bases relationnelles existent depuis plusieurs dizaines d'années, elles
sont fondées sur une théorie solide et ont fait l'objet d'innombrables
recherches, ce qui en fait les outils incontournables et aboutis qu'on connait
aujourd'hui. Toute concurrence est donc pour l'instant anecdotique.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Verdict&lt;/h3&gt;
&lt;p&gt;Conceptuellement, on voit bien le clivage entre les bases de type document
store qui recèlent le strict nécessaire permettant à une application de
fonctionner (le tout taillé sur mesure pour elle seule : une sorte de
YAGNI de la donnée), et un modèle relationnel qui essaie de capturer la réalité
de manière parfaite pour disposer d'une clé qui déverrouillera tous les
situations à venir.&lt;/p&gt;
&lt;p&gt;Sans prendre parti pour un camp ou l'autre, j'ai peur qu'à l'heure actuelle
les bases NoSQL manquent de maturité face aux mastodontes relationnels. Mais
elles restent une alternative à explorer et à mon avis, elles n'ont pas dit
leur dernier mot. La guerre est loin d'être finie.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2010/03/05/R%C3%A8glement-de-comptes-%C3%A0-Donn%C3%A9es-Corral#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2010/03/05/R%C3%A8glement-de-comptes-%C3%A0-Donn%C3%A9es-Corral#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/493100</wfw:commentRss>
      </item>
    
  <item>
    <title>En 2010, sachons lâcher du lest !</title>
    <link>http://blog.infosaurus.fr/post/2010/01/04/En-2010%2C-l%C3%A2chez-du-lest-%21</link>
    <guid isPermaLink="false">urn:md5:d51383cbb2ddc38843df66701ac9f9ef</guid>
    <pubDate>Mon, 04 Jan 2010 20:14:00 +0100</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Bric-à-brac</category>
        <category>Agile</category><category>Ecologie</category><category>TED</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/Balloon1.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.Balloon1_t.jpg&quot; alt=&quot;Ballon&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Ballon&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En ce début d'année, je vous propose de prendre un peu de hauteur en nous
élevant au-dessus des nuages.&lt;/p&gt;
&lt;p&gt;En Juillet dernier, l'aéronaute suisse Bertrand Piccard était invité à la
conférence TedGlobal 2009. Dans la vidéo de sa présentation récemment publiée
&lt;a href=&quot;http://www.ted.com/talks/bertrand_piccard_s_solar_powered_adventure.html&quot; hreflang=&quot;en&quot;&gt;sur le site de TED&lt;/a&gt;, Piccard nous raconte son tour du monde en
ballon avec Brian Jones et en tire une leçon que je trouve étonnamment en phase
avec les valeurs agiles.&lt;/p&gt;
&lt;p&gt;Dans cette discipline, explique le navigateur, s'opposer frontalement à un
fort vent contraire en voulant garder la même direction coûte que coûte, c'est
comme résister obstinément au changement dans la vie : cela peut
rapidement devenir un cauchemar.&lt;br /&gt;
Comment y remédier ? En comprenant que l'atmosphère est faite de couches
dans lesquelles le vent circule dans des directions diverses, et qu'il faut se
servir de l'axe vertical pour naviguer entre ces couches, par exemple en
lâchant du lest.&lt;br /&gt;
Pour Piccard, les pionniers, les découvreurs ne sont donc pas ceux qui font
face avec le plus d'acharnement aux difficultés rencontrées, ni même
nécessairement ceux qui ont les idées les plus nombreuses ou les plus
brillantes. Ce sont avant tout ceux qui osent jeter par-dessus bord leurs
convictions, leurs certitudes, leurs habitudes pour accéder à des courants qui
les mèneront à ce qu'ils cherchent par des voies de navigation
différentes.&lt;br /&gt;
On apprend que c'est aussi cet esprit précurseur et un peu utopiste qui a
gouverné le prochain projet de Bertrand Piccard, Solar Impulse, un avion
fonctionnant uniquement à l'énergie solaire et qui pourrait bientôt prendre son
envol autour du monde.&lt;/p&gt;
&lt;p&gt;Voici la vidéo :&lt;/p&gt;
&lt;div class=&quot;external-media&quot; style=&quot;margin: 1em auto; text-align: center;&quot;&gt;
&lt;object type=&quot;application/x-shockwave-flash&quot; data=&quot;http://blog.infosaurus.fr/?pf=player_flv.swf&quot; width=&quot;400&quot; height=&quot;300&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://blog.infosaurus.fr/?pf=player_flv.swf&quot; /&gt;
&lt;param name=&quot;wmode&quot; value=&quot;transparent&quot; /&gt;
&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot; /&gt;
&lt;param name=&quot;FlashVars&quot; value=&quot;margin=1&amp;amp;showvolume=1&amp;amp;showtime=1&amp;amp;showfullscreen=1&amp;amp;buttonovercolor=ff9900&amp;amp;slidercolor1=cccccc&amp;amp;slidercolor2=999999&amp;amp;sliderovercolor=0066cc&amp;amp;flv=http://video.ted.com/talks/dynamic/BertrandPiccard_2009G-medium.flv&amp;amp;width=400&amp;amp;height=300&quot; /&gt;&lt;/object&gt;&lt;br /&gt;

&lt;a href=&quot;http://video.ted.com/talks/dynamic/BertrandPiccard_2009G-medium.flv&quot;&gt;TED 2009
- Bertrand Piccard&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Voilà, je vous souhaite donc vous aussi de pouvoir lâcher tout le lest
nécessaire en cette nouvelle année afin de piloter votre ballon dans la
direction de vos rêves :)&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2010/01/04/En-2010%2C-l%C3%A2chez-du-lest-%21#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2010/01/04/En-2010%2C-l%C3%A2chez-du-lest-%21#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/473146</wfw:commentRss>
      </item>
    
  <item>
    <title>DDD Vite Fait, notions avancées</title>
    <link>http://blog.infosaurus.fr/post/2009/12/06/DDD-Vite-Fait%2C-notions-avanc%C3%A9es</link>
    <guid isPermaLink="false">urn:md5:a718f5f9e0d9eefb439adebfa426add5</guid>
    <pubDate>Sun, 06 Dec 2009 11:43:00 +0100</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Développement</category>
        <category>DDD</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/Page68.png&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.Page68_s.jpg&quot; alt=&quot;DDD Vite Fait Partie 2&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;DDD Vite Fait Partie 2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Comme promis, voici la deuxième partie de la traduction de DDD
Quickly : &lt;a href=&quot;http://blog.infosaurus.fr/public/docs/DDDViteFaitPartie2.pdf&quot;&gt;DDD Vite Fait,
partie 2&lt;/a&gt;, notions avancées.&lt;/p&gt;
&lt;p&gt;On y retrouve des techniques pour mettre en oeuvre DDD sur de gros projets
impliquant plusieurs équipes, mais aussi pour refactorer un domaine et gérer sa
croissance, notamment à travers la &lt;em&gt;distillation&lt;/em&gt; et l'identification
d'un &lt;em&gt;Coeur de Domaine&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Bonne lecture ;)&lt;/p&gt;
&lt;p&gt;(Mise à jour) : et voici le &lt;a href=&quot;http://blog.infosaurus.fr/public/docs/DDDViteFait.pdf&quot;&gt;fichier complet&lt;/a&gt; avec les deux parties.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2009/12/06/DDD-Vite-Fait%2C-notions-avanc%C3%A9es#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2009/12/06/DDD-Vite-Fait%2C-notions-avanc%C3%A9es#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/465262</wfw:commentRss>
      </item>
    
  <item>
    <title>Muramasa, the Demon Blade</title>
    <link>http://blog.infosaurus.fr/post/2009/11/21/Muramasa%2C-the-Demon-Blade</link>
    <guid isPermaLink="false">urn:md5:05034a2c1d75c95b86b770e69869ba19</guid>
    <pubDate>Sat, 21 Nov 2009 17:56:00 +0100</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Bric-à-brac</category>
        <category>Japon</category><category>Jeu vidéo</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/Muramasa/943228_20070921_screen006.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/Muramasa/.943228_20070921_screen006_t.jpg&quot; alt=&quot;Muramasa, the Demon Blade&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Muramasa, the Demon Blade&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Un fois n'est pas coutume, je vais vous parler d'un jeu vidéo. En fait, LE
jeu vidéo du moment pour moi, celui qui a débarrassé ma Wii de la grosse couche
de poussière qui s'y accumulait faute de titres intéressants ces derniers
temps : &lt;a href=&quot;http://www.muramasathedemonblade.com&quot; hreflang=&quot;en&quot;&gt;Muramasa, the Demon Blade&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Muramasa, c'est d'abord des graphismes sublimes, un petit joyau en 2D qui
s'approche de ce qui s'est fait de mieux artistiquement parlant sur cette
console. Des champs de blés dorés aux montagnes enneigées en passant par les
cerisiers en fleurs et les sombres forêts de bambous, ses décors typiquements
japonais nous en mettent plein la vue.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/Muramasa/phpN3hd7H.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/Muramasa/.phpN3hd7H_t.jpg&quot; alt=&quot;Des décors chatoyants&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Des décors chatoyants&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Ce qui est aussi intéressant avec ce jeu, c'est qu'il fait le pari que dans
les vieux pots on continue à faire les meilleures soupes (aux vermicelles).
Muramasa marque un retour à un genre old school, le bon vieux &lt;em&gt;beat'em
all&lt;/em&gt; par tableaux avec des cohortes d'ennemis à tuer et à la clé des boss
plus hideux et retors les uns que les autres. L'un des deux héros ninjas que
vous aurez choisi, Momohime ou Kisuke, part donc à l'aventure en enchainant des
combats aux règles très simples (seulement 4-5 coups différents) mais aux
possibilités démultipliées grâce aux caractéristiques propres des 108 (!)
sabres qu'il est possible d'acquérir. Il en résulte un gameplay vitaminé,
intuitif et fluide qui conserve tout de même une bonne dose de difficulté et
d'exigence héritée des jeux d'antan - surtout en mode Shura, le plus ardu.&lt;/p&gt;
&lt;p&gt;On note en plus de cela des petites touches d'originalité bienvenues qui
viennent agrémenter les parties, comme les recettes de cuisine qui permettent
de se &amp;quot;crafter&amp;quot; des bons petits repas pour regagner de l'énergie, ou des singes
menant à des sources chaudes où délasser et régénérer son corps.&lt;/p&gt;
&lt;p&gt;Bref, Muramasa démontre que c'est souvent en combinant des règles de base
très simples à des idées originales que l'alchimie peut opérer et qu'on arrive
à un résultat passionnant et unique... Si vous êtes fan d'atmosphère
médiévo-nippone et de combats virevoltants, je vous conseille de courir vous le
procurer si ce n'est déjà fait.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/Muramasa/muramasa-the-demon-blade-20081010112853001_640w.jpg&quot;&gt;
&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/Muramasa/.muramasa-the-demon-blade-20081010112853001_640w_t.jpg&quot; alt=&quot;Momohime en action&quot; title=&quot;Momohime en action&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/Muramasa/Muramasa04.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/Muramasa/.Muramasa04_t.jpg&quot; alt=&quot;Kisuke contre un samourai&quot; title=&quot;Kisuke contre un samourai&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/Muramasa/muramasa0804.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/Muramasa/.muramasa0804_t.jpg&quot; alt=&quot;Paysage enneigé&quot; title=&quot;Paysage enneigé&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2009/11/21/Muramasa%2C-the-Demon-Blade#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2009/11/21/Muramasa%2C-the-Demon-Blade#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/461437</wfw:commentRss>
      </item>
    
  <item>
    <title>Agile Tour Bordeaux 2009</title>
    <link>http://blog.infosaurus.fr/post/2009/10/30/Agile-Tour-2009-Bordeaux</link>
    <guid isPermaLink="false">urn:md5:99e240e9f7c8abcc4129435ea77b5c83</guid>
    <pubDate>Fri, 30 Oct 2009 18:29:00 +0100</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Méthodes et Entreprise</category>
        <category>Agile</category><category>Agile Tour</category><category>Scrum</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/Welcome_Agile_Tour.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.Welcome_Agile_Tour_s.jpg&quot; alt=&quot;Agile Tour 2009 Bordeaux&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Agile Tour 2009 Bordeaux&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Jeudi 29 Octobre 2009, l'Agile Tour faisait étape à Bordeaux, au &lt;a href=&quot;http://www.labri.fr/&quot; hreflang=&quot;fr&quot;&gt;LaBRI&lt;/a&gt;. J'étais de la partie et ma foi,
le bilan est plus que réjouissant. Au cours de la journée, les 150 participants
ont pu apprécier :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Des petites viennoiseries et du café pour bien entamer la journée.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;L'accueil des gentils organisateurs aux brassards roses très seyants
;-)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mais surtout,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Une foule de présentations et ateliers intéressants et instructifs... on
aurait parfois aimé pouvoir se dédoubler pour être dans plusieurs salles à la
fois.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Du côté des coups de coeur, j'ai été bluffé par le retour d'expérience Scrum
de Philippe Launay de la société Agfa. Réussir à introduire l'agilité dans un
projet avec des équipes multi-localisées sur plusieurs pays, des milliers
d'utilisateurs, un périmètre tentaculaire et en partant avec de sévères
handicaps techniques et organisationnels relève du tour de force.
L'amélioration continue des équipes permise par la méthode est assez
spectaculaire, et les leçons à en tirer très instructives.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/AgileTour_Badge.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.AgileTour_Badge_t.jpg&quot; alt=&quot;Badge Agile Tour&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Badge Agile Tour&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;J'ai cependant regretté :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ne pas avoir pu participer à la session TDD donnée par C. Couillard et
&lt;a href=&quot;http://www.bodysplash.fr/&quot;&gt;J-B Dusseaut&lt;/a&gt; tellement c'était blindé
de monde...&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Certains ateliers alléchants (dont le &amp;quot;bateau ivre&amp;quot; animé entre autres par
&lt;a href=&quot;http://pyxis-tech.com/en/lequipe/#rpierquin&quot; hreflang=&quot;en&quot;&gt;Raphaël
Pierquin&lt;/a&gt;) très limités en nombre de places. Dommage, mais je n'ai pas perdu
au change avec le retour d'expérience de Philippe Launay.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Un vidéoprojecteur rebelle a décidé de saboter la présentation
&amp;quot;Contractualisation agile&amp;quot; qui du coup a pris du plomb dans l'aile malgré toute
la bonne volonté de l'orateur...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;
&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/Agile_Tour_Conclusion.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.Agile_Tour_Conclusion_t.jpg&quot; alt=&quot;Le mot de la fin&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Le mot de la fin&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Au final, cet Agile Tour fut pour moi très instructif et enrichissant. Bravo
aux organisateurs qui ont su rassembler autant de talents et favoriser
rencontres et échanges d'expériences tout au long de cette journée très
réussie !&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2009/10/30/Agile-Tour-2009-Bordeaux#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2009/10/30/Agile-Tour-2009-Bordeaux#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/456338</wfw:commentRss>
      </item>
    
  <item>
    <title>Tous des moutons ! Peut-être, et alors ?</title>
    <link>http://blog.infosaurus.fr/post/2009/10/27/Tous-des-moutons-Peut-%C3%AAtre%2C-et-alors</link>
    <guid isPermaLink="false">urn:md5:cbfa92062cdb4a84d0a0c81152a318c3</guid>
    <pubDate>Tue, 27 Oct 2009 21:12:00 +0100</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Méthodes et Entreprise</category>
        <category>Agile</category><category>Linda Rising</category>    
    <description>    &lt;p&gt;Connaissez-vous la doyenne de l'agilité ? La super mamie des
itérations ? La matriarche des rétrospectives ? Non ? Et bien
laissez-moi vous présenter &lt;a href=&quot;http://www.lindarising.org/&quot; hreflang=&quot;en&quot;&gt;Linda Rising&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;J'aime bien Linda car en plus d'être un peu barrée, elle nous emmène dans
des sujets scientifiques originaux et passionnants qui restent tout de même en
rapport avec une des choses qui intéressent la bande de geeks que nous
sommes : les projets informatiques.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.infoq.com/interviews/rising-on-placebos&quot; hreflang=&quot;en&quot;&gt;Cette fois-ci&lt;/a&gt; Linda revient pour nous parler des Placebos. Pas le
groupe de rock, les médicaments... Il s'avère que ces traitements (en fait des
non-traitements) sont employés plus souvent qu'on ne le pense par les médecins,
et que leur effet se révèle dans certains cas autant voire plus efficace que
celui de médicaments classiques. Un chercheur a essayé d'en savoir plus sur cet
effet difficilement explicable, et en particulier sur les gens les plus
susceptibles de développer un effet placebo. Il a appelé ces personnes les
&amp;quot;moutons&amp;quot; (&lt;em&gt;sheep&lt;/em&gt;). De manière assez singulière, au fil des recherches,
les moutons se sont avérés être des personnes particulièrement créatives,
innovantes, curieuses, ouvertes à de nouvelles idées et expériences. En somme,
les plus enclins à appliquer avec enthousiasme le célèbre adage de Fox
Mulder : &amp;quot;&lt;em&gt;I want to believe&lt;/em&gt;&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/curious_sheep.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.curious_sheep_s.jpg&quot; alt=&quot;Bande de curieux&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Bande de curieux&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Linda s'est alors aperçue que ce genre de bestiole constituait, entre
autres, un assez bon portrait des enthousiastes de l'agilité. Et en effet le
parallèle ne parait pas usurpé : les valeurs mises en avant dans les
méthodes agiles sont l'ouverture d'esprit, le désir d'expérimenter en
permanence, de tester et de tirer les leçons de ses actions pour s'améliorer.
En y réfléchissant bien, cela relève d'une volonté primordiale de croire en ce
qu'on fait, d'avoir foi en sa propre inventivité. Si nous n'y croyions pas un
petit peu, nous ne mettrions pas autant d'efforts à essayer.&lt;/p&gt;
&lt;p&gt;Mais du coup, les méthodes agiles ne seraient-elles pas elles-mêmes des
placebos ?&lt;/p&gt;
&lt;p&gt;Les équipes agiles ne fonctionneraient-elles pas uniquement parce que leurs
membres, en bons moutons, s'auto-persuadent du bien fondé de la vision et de la
démarche de leur méthode préférée, et avancent ainsi de manière plus sereine,
plus impliquée et donc plus productive ?&lt;/p&gt;
&lt;p&gt;Si c'était le cas, cela remettrait-il en cause l'efficacité intrinsèque de
l'agilité ?&lt;/p&gt;
&lt;p&gt;Est-ce qu'on devrait s'en inquiéter ?&lt;/p&gt;
&lt;p&gt;La meilleure réponse à toutes ces questions consiste peut-être à se rappeler
que l'effet placebo n'est pas seulement l'apanage des cachets en sucre et
autres gélules remplies de farine. Même les vrais médicaments peuvent avoir un
effet placebo, certaines recherches le montrent. Dans quelle proportion cet
effet rentre dans le processus de guérison, cela dépend sans doute du
traitement et de la personne, et le &amp;quot;vrai&amp;quot; effet est certainement très
difficile à dissocier de la part de placebo.&lt;br /&gt;
Mais dans bien des cas, cette part existe bel et bien, et elle n'est pas
forcément négligeable...&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2009/10/27/Tous-des-moutons-Peut-%C3%AAtre%2C-et-alors#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2009/10/27/Tous-des-moutons-Peut-%C3%AAtre%2C-et-alors#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/454846</wfw:commentRss>
      </item>
    
  <item>
    <title>Impressions sur Visual Studio 2010</title>
    <link>http://blog.infosaurus.fr/post/2009/10/22/Impressions-sur-Visual-Studio-2010</link>
    <guid isPermaLink="false">urn:md5:a0414f90077b8655cd49321e12e77fff</guid>
    <pubDate>Thu, 22 Oct 2009 20:25:00 +0200</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Développement</category>
        <category>.NET</category><category>ReSharper</category><category>Visual Studio 2010</category>    
    <description>    &lt;p&gt;La béta 2 de Visual Studio 2010 étant sortie il y a peu, il était grand
temps pour moi de voir ce que cette nouvelle mouture de l'IDE de Microsoft
avait sous le capot.&lt;/p&gt;
&lt;p&gt;Un tour sur la &lt;a href=&quot;http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx&quot;&gt;page de download&lt;/a&gt; de
la béta, et après un processus d'installation classique mais efficace, la
nouvelle interface s'offre à nos yeux.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/VS_Accueil.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.VS_Accueil_s.jpg&quot; alt=&quot;Visual Studio 2010&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Visual Studio 2010&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Bon, à part une couleur bleu horizon du plus bel effet, on ne peut pas dire
que la page de démarrage soit une révolution par rapport à Visual Studio 2008.
Nouveau/Ouvrir Projet, Projets récents, quelques nouveaux liens comme la
personnalisation de la page d'accueil, les habitués ne seront pas dépaysés.&lt;/p&gt;
&lt;p&gt;Lorsqu'on ouvre un solution et qu'on commence à jouer avec la bête, petite
déception : l'interface ne semble pas très réactive. Même si c'est
pardonnable pour une béta, on constate à l'usage beaucoup de lenteurs et même
quelques freezes momentanés (machine sous Windows Vista, Core 2 Duo 2 GHz, 4 Go
de RAM). Peut-être la faute à l'IHM basée sur du WPF.&lt;/p&gt;
&lt;p&gt;Mais voyons maintenant les principales nouveautés autour de ce qui nous
intéresse le plus : la manipulation du code.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Navigation&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/VS_Navigation.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.VS_Navigation_s.jpg&quot; alt=&quot;Quick Search&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Quick Search&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Les développeurs de Visual 2010 avaient annoncé une navigabilité dans le
code grandement améliorée, et c'est certainement un des domaines où le plus de
progrès ont été faits. Voici les avancées les plus marquantes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Quick Search : activée par un Ctrl-virgule, cette boite de dialogue
permet une recherche intuitive avec suggestion de résultat lorsqu'on tape les
premières lettres d'une classe ou les majuscules qui composent son nom. En
fait, un passage incontournable pour naviguer entre vos fichiers/classes,
tellement il est pratique.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Surlignage de références : lorsque le curseur se trouve sur une
variable, méthode ou type, après quelques instants celle-ci est discrètement
surlignée ainsi que toutes ses occurrences dans le fichier actif. Une aide
visuelle non négligeable qui évite de chercher les références
manuellement.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Hiérarchie des appels : cette nouvelle fonctionnalité affiche un arbre
contenant les appels à la méthode/property sélectionnée, les appels au code qui
l'appellent, et ainsi de suite. Cela évite de faire des &amp;quot;find usages&amp;quot;
successifs lorsqu'on veut remonter une pile d'appels dans le code.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Refactoring&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/VS_Refacto.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.VS_Refacto_s.jpg&quot; alt=&quot;Smart tag&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Smart tag&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Au système d'affichage d'erreurs à la volée déjà existant, les développeurs
de Visual Studio 2010 ont ajouté, exactement à la manière d'un &lt;a href=&quot;http://www.jetbrains.com/resharper/index.html&quot; hreflang=&quot;en&quot;&gt;ReSharper&lt;/a&gt;,
des petites boîtes de suggestion (les SmartTags) qui lorsqu'elles sont
déroulées proposent un menu avec diverses actions de refactoring et de
génération de code.&lt;/p&gt;
&lt;p&gt;Si certaines sont utiles en toute occasion (implémentation/héritage
automatique, suggestion d'ajout de références...), d'autres sont clairement
orientées TDD comme la génération de stubs de classe ou de méthodes qui
n'existent pas encore.&lt;br /&gt;
Le raccourci pour les SmartTags est Ctrl-point-virgule.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3&gt;Un tueur de ReSharper ? Pas vraiment&lt;br /&gt;
&lt;br /&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/Visual_Resharper.jpg&quot; alt=&quot;VS2010-ReSharper&quot; style=&quot;float:left; margin: 0 1em 1em 0;&quot; title=&quot;VS2010-ReSharper&quot; /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;Au vu de ces éléments, on pourrait penser que Microsoft a encore fait ce
qu'il sait le mieux faire, c'est à dire copier les innovations de plus petits
acteurs du marché pour les intégrer et les généraliser dans ses mastodontes. Le
petit poucet innovant étant dans le cas présent JetBrains avec son ReSharper,
plug-in tellement utile à la vie du développeur (il comportait déjà bon nombre
des fonctionnalités de VS 2010 citées ci-dessus dès ses premières versions)
qu'on avait du mal à s'en passer.&lt;br /&gt;
Le problème, c'est que Microsoft a copié cette recette à succès, mais en
oubliant quelques ingrédients. Il manque à Visual 2010 tout un tas de petites
fonctions de ReSharper qui me font dire que ce dernier sera toujours
indispensable :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pas de fermeture automatique des accolades&lt;/li&gt;
&lt;li&gt;Pas d'autocomplétion des noms de variables avec un nom par défaut&lt;/li&gt;
&lt;li&gt;Pas de go to Inheritor / base&lt;/li&gt;
&lt;li&gt;Pas de surlignage des erreurs à la volée pour certains types d'erreurs
(ex : non implémentation d'une interface)&lt;/li&gt;
&lt;li&gt;SmartTags mal placés : par exemple sur le nom de la classe mère après
les deux points d'un héritage, mais pas sur le nom de la classe fille donc peu
visible&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Au final, après quelques heures de manipulation de Visual Studio 2010, mon
impression est qu'il n'est toujours pas aussi facile à piloter qu'un 2008 +
ReSharper. Il manque cette réactivité, cette intuitivité qui font que l'IDE
semble répondre au doigt et à l'oeil du développeur et lui apporte une
productivité maximum.&lt;/p&gt;
&lt;p&gt;Si l'on ajoute que JetBrains met la barre encore plus haut pour le futur
&lt;a href=&quot;http://blogs.jetbrains.com/dotnet/2009/10/resharper-50-overview/&quot;&gt;ReSharper
5&lt;/a&gt;, je pense que le petit plug-in a encore de beaux jours devant lui...&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2009/10/22/Impressions-sur-Visual-Studio-2010#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2009/10/22/Impressions-sur-Visual-Studio-2010#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/453482</wfw:commentRss>
      </item>
    
  <item>
    <title>DDD Vite Fait, les fondamentaux de Domain Driven Design</title>
    <link>http://blog.infosaurus.fr/post/2009/10/13/DDD-Vite-Fait%2C-les-fondamentaux-de-DDD</link>
    <guid isPermaLink="false">urn:md5:8f8c29bfc3265acf3c8a57fad1e9e1b2</guid>
    <pubDate>Wed, 14 Oct 2009 21:29:00 +0200</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Développement</category>
        <category>DDD</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/DDDViteFait.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.DDDViteFait_s.jpg&quot; alt=&quot;DDD Vite Fait&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;DDD Vite Fait&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dans mon précédent billet, j'évoquais l'importance à mes yeux de l'approche
collaborative du développement logiciel qu'apporte Domain Driven Design et je
vous parlais d'un travail en cours sur DDD.&lt;/p&gt;
&lt;p&gt;Et bien le voici : &lt;em&gt;DDD Vite Fait&lt;/em&gt;, première partie - les
fondamentaux de DDD.&lt;/p&gt;
&lt;p&gt;Ce livre (en version originale &lt;em&gt;&lt;a href=&quot;http://www.infoq.com/minibooks/domain-driven-design-quickly&quot;&gt;DDD
Quickly&lt;/a&gt;&lt;/em&gt;, par A. Avram et F. Marinescu) présente tous les concepts et
patterns qui forment la base de Domain Driven Design. Le texte est voulu comme
une courte introduction - 54 pages tout de même ! - avec comme but avoué
&lt;del&gt;l'hégémonie planétaire de DDD&lt;/del&gt; de diffuser la vision initiée par
l'auteur Eric Evans et faire (re)découvrir Domain Driven Design, approche de
développement logiciel parfois mal connue en France.&lt;/p&gt;
&lt;p&gt;Vous pouvez télécharger le PDF de la version française &lt;a href=&quot;http://blog.infosaurus.fr/public/docs/DDDViteFaitPartie1.pdf&quot;&gt;ici&lt;/a&gt; ou sur le site &lt;a href=&quot;http://www.dddfrance.org/DDDViteFait&quot;&gt;DDDFrance&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Un grand merci à Floyd Marinescu pour m'avoir autorisé à traduire son
ouvrage, et rendez-vous dans quelques semaines pour découvrir la deuxième
partie : DDD, notions avancées...&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2009/10/13/DDD-Vite-Fait%2C-les-fondamentaux-de-DDD#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2009/10/13/DDD-Vite-Fait%2C-les-fondamentaux-de-DDD#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/449339</wfw:commentRss>
      </item>
    
  <item>
    <title>Smells DDD, quand votre domaine sent des pieds</title>
    <link>http://blog.infosaurus.fr/post/2009/10/01/Smells-DDD</link>
    <guid isPermaLink="false">urn:md5:015aa63f5575885cae9dde3833bff380</guid>
    <pubDate>Thu, 01 Oct 2009 20:16:00 +0200</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Développement</category>
        <category>Code smells</category><category>DDD</category><category>Entreprise</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/2098009377_b355a8aae6.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.2098009377_b355a8aae6_t.jpg&quot; alt=&quot;Smell&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Smell&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En ce moment, je me replonge dans Domain Driven Design, l'approche du
développement logiciel orientée domaine initiée par Eric Evans. Il m'est
subitement apparu une chose que je ne m'étais jamais représentée auparavant,
certainement parce que j'avais abordé le sujet avant tout par son aspect
technique : le plus important à mon avis dans DDD, ce ne sont pas les
patterns, c'est la philosophie de la modélisation collaborative du domaine.&lt;/p&gt;
&lt;p&gt;Comprenez-moi bien, j'estime que les design patterns évoqués dans DDD sont
brillants, ce sont des guides précieux pour développer un code du domaine
clair, maintenable et faiblement couplé. Mais pour moi, l'essence de DDD ne
réside pas là. Elle réside dans la collaboration étroite entre experts métiers,
concepteurs et développeurs pour construire un modèle du domaine qui reflète la
réalité et permet de résoudre de vraies problématiques métier. Elle réside dans
la constitution d'un langage commun qui, en plus de faciliter la compréhension
du métier par les personnes techniques, instaure dialogue et confiance au sein
de l'équipe projet. Car je pense que c'est cela qui, au final, permet de faire
du bon logiciel.&lt;/p&gt;
&lt;p&gt;Je me suis sans doute heurté à ce constat car ce n'est pas du tout le cas
dans l'organisation dans laquelle je travaille actuellement. Ca serait même
plutôt le contraire. La forme de communication privilégiée est le fichier Word
de besoin, de recette ou le ticket d'outil de gestion de bugs. Les
conversations téléphoniques sont rares et ont souvent lieu en famille, entre
développeurs ou entre experts métier. Sans parler de vraies rencontres entre
développement et métier, inexistantes. Une méfiance d'origine floue entre les
deux camps a installé une guéguerre perpétuelle MOE/MOA, les uns accusant les
autres d'en demander toujours trop et de changer sans cesse de besoin ;
les seconds soupçonnant les premiers d'être des tire-au-flanc. Du coup, l'idée
de base chez la MOE est de se conformer à la virgule près aux documents, tels
des actes notariaux, et chez la MOA d'en fourrer le plus possible dans lesdits
documents. Bien sûr, c'est la connaissance du domaine qui en pâtit, tant
l'incompréhension est grande. Il est même surprenant de voir que des
développeurs avec plusieurs années dans l'organisation n'ont qu'une vision
parcellaire et approximative du métier. Au final, le résultat se ressent dans
la qualité du logiciel.&lt;/p&gt;
&lt;p&gt;D'ailleurs - et ça ne s'applique pas seulement à mon exemple - de tels
problèmes refont souvent surface sous la forme de code smells qu'on pourrait
appeler &lt;em&gt;Domain smells&lt;/em&gt;. Je me suis amusé à en recenser
quelques-uns :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Domaine fantôme&lt;/strong&gt; : ça peut paraître abérrent, mais il
n'y a pas de couche domaine dans le projet dont je parle, en partie à cause de
la technologie employée. Le métier est fondu dans la masse du reste du code. Il
va sans dire qu'une couche domaine séparée est indispensable, pour toutes les
raisons de découplage, de lisibilité... qu'on peut imaginer.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Domaine râpé&lt;/strong&gt; : On constate aussi parfois que des
bouts de domaine sont saupoudrés dans des couches différentes, le plus dur
étant de ne pas être tenté d'en mettre dans la couche présentation. Même si ça
peut être justifié, il vaut mieux pour la maintenabilité de l'application
conserver au même endroit tous les éléments liés au domaine.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Domaine indéchiffrable&lt;/strong&gt; : un des principes de DDD est
que le code du domaine doit être clair et compréhensible, et donner tout de
suite une vision d'ensemble à celui qui y jette un oeil. Malheureusement ce
n'est pas toujours le cas, souvent à cause d'une représentation brouillonne du
domaine dans le code dûe à un manque de dialogue avec les experts métier. De
plus il est facile de se perdre en créant toujours plus de helpers, de services
et autres gestionnaires qui embrouillent la compréhension du domaine.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Abus de notion&lt;/strong&gt; : qui n'a jamais été confronté au
mot-valise du domaine, à la notion métier un peu floue qui se retrouve toutes
les trois lignes de code dans chaque module de l'application ? Comme si un
développeur avait trouvé que le mot sonnait bien et décidé de l'utiliser aussi
fréquemment que possible. C'est souvent le signe d'une modélisation pas assez
en profondeur, d'un concept du domaine qui recouvre trop d'aspects et devrait
sans doute être subdivisé.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Frères jumeaux&lt;/strong&gt; : parfois c'est l'inverse, deux mots
différents sont employés à travers l'application pour recouvrir la même notion
métier. Cela peut mener à penser qu'il s'agit de deux choses différentes, ce
qui est source de confusion. Convenir d'un seul terme précis et bien identifié
permettra d'éviter les malentendus.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Déphasage de concept&lt;/strong&gt; : ce smell se fait sentir
lorsqu'on interroge un expert métier sur une notion présente dans le code du
domaine, et qu'on s'aperçoit qu'elle est en total décalage avec la réalité,
même si l'application semble se comporter correctement pour l'utilisateur. Il
peut s'agir d'une mauvaise interprétation ou d'une supposition hasardeuse de la
part d'un développeur. En tout cas, le code est à reprendre et la communication
est à revoir.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Je vois d'ici certains dire &amp;quot;C'est bien beau, mais les experts métier ne
sont pas souvent disponibles et une communication écrite restreinte est mieux
que pas de communication du tout.&amp;quot; Bien sûr, mais après tout, n'est-ce pas dans
l'intérêt de la personne métier d'avoir une collaboration aussi efficace que
possible avec le développeur qui réalisera l'application pour lui ?
N'est-ce pas primordial de s'assurer qu'il est au diapason de la réalité du
domaine ?&lt;/p&gt;
&lt;p&gt;Même si l'expert métier ne peut pas se rendre souvent disponible, il devrait
l'être autant que faire se peut. Une solution au problème pourrait être de
timeboxer les scéances de conception collaborative. Parfois, un dialogue d'une
demi-heure bien cadré et sans perturbation peut être plus efficace qu'une
réunion décousue de deux heures, qui aura pourtant demandé plus de
disponibilité à l'expert du domaine...&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2009/10/01/Smells-DDD#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2009/10/01/Smells-DDD#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/446220</wfw:commentRss>
      </item>
    
  <item>
    <title>Formation Scrum Master par Pyxis</title>
    <link>http://blog.infosaurus.fr/post/2009/09/27/Formation-Certified-Scrum-Master-chez-Pyxis</link>
    <guid isPermaLink="false">urn:md5:af578ceacc39ae275a4f5d77b1f0705b</guid>
    <pubDate>Wed, 30 Sep 2009 20:18:00 +0200</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Méthodes et Entreprise</category>
        <category>Agile</category><category>Scrum</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/IMAG0169.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.IMAG0169_s.jpg&quot; alt=&quot;Formation Scrum Master Pyxis&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Formation Scrum Master Pyxis&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Il y a quelques jours, j'ai eu la chance de suivre la formation Certified
Scrum Master donnée par François Beauregard, fondateur de la société &lt;a href=&quot;http://pyxis-tech.com/fr/&quot; hreflang=&quot;fr&quot;&gt;Pyxis&lt;/a&gt;. Le tout se déroulait dans
un bel endroit, le Centre culturel canadien situé à deux pas des Invalides.&lt;/p&gt;
&lt;p&gt;Au programme de ces deux jours très remplis, théorie (rôles, cérémonies,
artefacts, 4 piliers de Scrum), bonnes pratiques, ateliers, séances de
questions/réponses avec le formateur... Du forfait agile au sprint zéro en
passant par les équipes distribuées, de multiples débats ont été soulevés. J'en
aborderai peut-être quelques uns ici.&lt;/p&gt;
&lt;p&gt;Au-delà de l'aspect formation certifiante (que François a d'ailleurs
beaucoup mitigé), je suis surtout reparti tel un gamin après une récréation
fructueuse, avec un sac de billes Scrum bien rempli !&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/IMAG0165.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.IMAG0165_sq.jpg&quot; alt=&quot;Centre culturel canadien&quot; title=&quot;Centre culturel canadien&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/IMAG0167.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.IMAG0167_sq.jpg&quot; alt=&quot;La salle de formation&quot; title=&quot;La salle de formation&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/IMAG0170.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.IMAG0170_sq.jpg&quot; alt=&quot;Atelier Product Backlog&quot; title=&quot;Atelier Product Backlog&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/IMAG0171.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.IMAG0171_sq.jpg&quot; alt=&quot;Atelier Product Backlog&quot; title=&quot;Atelier Product Backlog&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/IMAG0172.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.IMAG0172_sq.jpg&quot; alt=&quot;Les post-its de clôture&quot; title=&quot;Les post-its de clôture&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2009/09/27/Formation-Certified-Scrum-Master-chez-Pyxis#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2009/09/27/Formation-Certified-Scrum-Master-chez-Pyxis#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/445118</wfw:commentRss>
      </item>
    
  <item>
    <title>Agilité et développement durable, victimes de leur trop bel emballage ?</title>
    <link>http://blog.infosaurus.fr/post/2009/09/22/Agilit%C3%A9-et-d%C3%A9veloppement-durable%2C-victimes-de-leur-trop-bel-emballage</link>
    <guid isPermaLink="false">urn:md5:505502e740b3371376608d699bd4b544</guid>
    <pubDate>Tue, 22 Sep 2009 19:25:00 +0200</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Méthodes et Entreprise</category>
        <category>Agile</category><category>ARxTA</category><category>Ecologie</category>    
    <description>    &lt;p&gt;Il y a peu, j'entendais Cécile Duflot, secrétaire nationale des Verts,
parler de développement durable dans une émission. Selon elle, ce terme a été
dévoyé. Agréable à l'oreille, exprimant à merveille l'idée d'un système
économique plus respectueux de l'environnement, il a été repris par toutes les
multinationales qui se revendiquent maintenant &lt;em&gt;développement durable&lt;/em&gt; à
l'apparition de la moindre bribe de carton recyclé dans un de leurs produits.
Un exemple frappant est celui du groupe Pinault-Printemps-Redoute, qui s'est
royalement offert plusieurs minutes d'auto promotion un peu usurpée dans le
générique d'ouverture du film Home de Yann-Arthus Bertrand.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/366ca_method-packaging.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.366ca_method-packaging_s.jpg&quot; alt=&quot;Packaging&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Packaging&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Depuis quelques temps, on a l'impression qu'il se passe la même chose avec
les méthodes agiles. Dans les plaquettes commerciales, sur les sites Web, dans
les offres d'emploi des sociétés informatiques, Agile est partout, il est
devenu très tendance d'être agile même si on ne comprend pas un traitre mot à
ce que cela veut dire et qu'on est la société la moins bien placée du monde
pour en parler. Autre marqueur inquiétant de l'inflation du buzzword, lorsqu'on
discute du sujet avec certains responsables informatiques qui n'ont pas encore
&amp;quot;sauté le pas&amp;quot;, ceux-ci s'excusent maintenant presque de ne pas être agiles,
non pas parce qu'ils regrettent de ne pas profiter de la révolution apportée
par la pratique de Scrum ou XP mais juste comme on s'excuserait de ne pas être
à la page, de ne pas posséder la dernière BMW ou le dernier IPhone top
tendance.&lt;/p&gt;
&lt;p&gt;Et c'est vrai que le mot Agile sonne diablement bien, trop bien diront
certains. Quelle solution adopter contre cette surexploitation qui finit par
lui faire perdre tout son sens ?&lt;/p&gt;
&lt;p&gt;Pour revenir à Cécile Duflot, elle a ensuite expliqué ce qui avait émergé en
réaction à ce contexte de surmédiatisation et d'aseptisation de l'écologie.
Puisque tout le monde était &lt;em&gt;développement durable&lt;/em&gt;, être développement
durable ne voulait plus dire grand-chose. C'est alors que certains écolos ont
repris et donné de l'écho à l'idée de &lt;em&gt;décroissance&lt;/em&gt; - qui existait déjà
depuis fort longtemps. Le mot &lt;em&gt;décroissant&lt;/em&gt; paraissait tellement brutal,
soulevait un tel nuage d'a prioris négatifs à la fois chez le grand public et
chez les acteurs économiques, qu'au moins aucune multinationale ne s'amuserait
à le reprendre à son compte.&lt;br /&gt;
Le problème avec les visions radicales, ou dont l'appellation évoque tout de
suite la radicalité, est qu'elles sont condamnées à rester cloitrées au sein de
petits groupes d'activistes, et garanties ne jamais voir leurs idées se
diffuser dans les moeurs. Une fois la notion de décroissance expliquée au grand
public par les médias, le rejet et la méfiance n'ont donc pas tardé à
apparaitre, les décroissants passant pour une bande d'illuminés - ce qui est
bien résumé dans &lt;a href=&quot;http://www.youtube.com/watch?v=zUuLjmnM3Zw&quot; hreflang=&quot;fr&quot;&gt;cette pub&lt;/a&gt;, hilarante, qui les ridiculise sans les nommer.&lt;/p&gt;
&lt;p&gt;Vous vous en doutez, un concept similaire a fait son apparition dans le
monde des méthodes agiles. Il s'agit de l'&lt;a href=&quot;http://arxta.net/&quot; hreflang=&quot;en&quot;&gt;ARxTA&lt;/a&gt; (Artisanal Retro-Futurism crossed with Team-Scale
Anarcho-Syndicalism !) proposé par &lt;a href=&quot;http://www.infoq.com/presentations/marick-retro-futurism&quot; hreflang=&quot;en&quot;&gt;Brian
Marick&lt;/a&gt;. Il va sans dire que l'acronyme imprononçable et l'explication
compliquée provoqueront des réactions mêlées d'effroi et d'assoupissement chez
les interlocuteurs à qui vous parlerez de ce mouvement. C'est le but, et même
si ce qui se cache derrière ces termes est passionnant et pertinent, on n'a vu
jusqu'ici aucun courant marketing s'emparer du concept.&lt;br /&gt;
Pour autant, Brian Marick qui comptait en réalité administrer à la communauté
une piqûre de rappel salutaire sur ce qu'étaient les fondements de l'agilité,
n'a semble-t-il malheureusement réussi qu'à prêcher des convaincus. Son action
radicale n'a pour l'heure pas vraiment fait contrepoids au dépouillement de
tout sens qui semble parfois aller de pair avec le succès des méthodes
agiles.&lt;/p&gt;
&lt;p&gt;Pour conclure, je pense qu'il reste toujours à trouver un juste milieu entre
mode marketée qui alimente un buzz déraisonné, et concept aride connu d'un
petit cercle de nerds en chemises à carreaux. Les manifestes (agile, software
craftsmanship, ARxTA...), même s'ils conviennent parfaitement à l'idée qu'il ne
s'agit pas de normes mais juste de philosophies qu'on peut pratiquer au
quotidien, semblent bien en peine d'éviter d'être vidés d'une partie de leur
substance en même temps qu'ils deviennent &amp;quot;grand public&amp;quot;. Certains affirment
que la constitution d'entités plus formelles et garantes des bonnes pratiques,
peut-être sous la forme de certifications, serait une solution. En tout cas, vu
les récentes &lt;a href=&quot;http://www.agilealliance.org/show/1796&quot; hreflang=&quot;en&quot;&gt;déclarations de l'Agile Alliance&lt;/a&gt;, on ne semble pas en prendre le
chemin...&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2009/09/22/Agilit%C3%A9-et-d%C3%A9veloppement-durable%2C-victimes-de-leur-trop-bel-emballage#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2009/09/22/Agilit%C3%A9-et-d%C3%A9veloppement-durable%2C-victimes-de-leur-trop-bel-emballage#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/443858</wfw:commentRss>
      </item>
    
  <item>
    <title>Le mouton noir des pratiques d'ingéniérie</title>
    <link>http://blog.infosaurus.fr/post/2009/09/19/Pair-Programming%2C-le-mouton-noir-des-pratiques-d-ing%C3%A9ni%C3%A9rie</link>
    <guid isPermaLink="false">urn:md5:d2db1b3fe8834acaaa10e760f2a48029</guid>
    <pubDate>Sat, 19 Sep 2009 19:55:00 +0200</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Méthodes et Entreprise</category>
        <category>Agile</category><category>Pair Programming</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/2561252664_88b19dc2b7.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.2561252664_88b19dc2b7_s.jpg&quot; alt=&quot;Un mouton noir parmi les brebis vertueuses&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Un mouton noir parmi les brebis vertueuses&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Il est en ce moment un nom qui provoque des frissons d'indignation chez les
DSI et les managers. Une pratique qui, même dans certaines organisations ayant
adopté intégration continue et TDD au sein de leurs équipes de développement,
reste un tabou autour duquel gravitent beaucoup d'idées reçues. Cette pratique
mal-aimée, du moins en France, c'est le Pair Programming.&lt;/p&gt;
&lt;p&gt;Qui n'a jamais entendu la réflexion suivante : &amp;quot;La programmation en
binôme, c'est payer deux développeurs pour faire le travail d'un seul. Ma
direction n'acceptera jamais ça.&amp;quot; Il y a peu j'ai même entendu de la part d'une
société qui pratique pourtant d'autres techniques d'ingénierie agiles au
quotidien : &amp;quot;Nous ne sommes que quatre développeurs, vous comprenez qu'on
ne peut pas se permettre ce genre de façon de travailler !&amp;quot;&lt;/p&gt;
&lt;p&gt;Pourtant, les études montrant l'efficacité du Pair Programming ne manquent
pas. Le chiffre habituellement donné est celui d'un développement 15% plus lent
qu'avec deux développeurs séparés mais qui produit 15% de bugs en moins. Quand
on sait que le temps de debug et de test est souvent bien plus long que le
temps de développement initial, un tel gain de qualité n'est pas négligeable.
Des &lt;a href=&quot;http://simula.no/research/engineering/publications/Arisholm.2006.2/simula_pdf_file&quot; hreflang=&quot;en&quot;&gt;études plus récentes&lt;/a&gt; vont plus loin, affirmant que pour des
logiciels complexes, le Pair Programming apporte en moyenne un gain de qualité
de 48% sans qu'il y ait de différence significative au niveau des délais.&lt;/p&gt;
&lt;p&gt;Au-delà des chiffres, il y a le constat d'amélioration omniprésent lorsqu'on
pratique le Pair Programming sur une période de temps significative. Pour
l'avoir expérimenté entre autres en tant que membre d'une équipe à la fois
nombreuse (10 à 15 développeurs) et hétérogène en termes de maturité sur le
projet et d'expertise technique, les effets constatés sont assez
spectaculaires :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Diffusion rapide de la connaissance du domaine à tous les membres de
l'équipe&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Montée en compétence technique favorisée par le binomage expert-novice (le
novice ne se contentant pas d'écouter, il agit aussi, lorsqu'il a le
clavier)&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Choix de conception et d'implémentation de meilleure qualité, fruits de la
réflexion conjointe et de la confrontation d'idées des deux coéquipiers&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Moins de perte de temps et de déconcentration, le copilote servant de
barrière de sécurité pour rester dans les rails de l'objectif fixé&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Emulation au sein de chaque binôme et de l'équipe entière&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bien sûr, il ne s'agit pas de partir la fleur au fusil pour une colocation à
durée indéterminée avec le collègue avec qui on se marrera le mieux. Il y a une
rigueur à adopter et certaines règles de conduite nous y aident. Par exemple,
le fait de timeboxer systématiquement les scéances de pairing, et de changer de
coéquipier régulièrement (toutes les semaines, tous les jours, toutes les
demi-journées, à l'équipe de trouver son rythme).&lt;/p&gt;
&lt;p&gt;Je ne suis pas non plus partisan du 100% Pair Programming. Il y a certaines
tâches de codage, parmi celles les plus répétitives et nécessitant le moins de
réflexion et d'arbitrages, qu'un développeur peut, avec autant de qualité et
plus d'efficacité, assurer seul.&lt;br /&gt;
En revanche, le binomage me parait être d'un bénéfice tellement évident pour
certaines autres activités que je ne vois pas bien comment s'en passer. Par
exemple, lorsqu'il s'agit d'intégrer un nouveau membre dans l'équipe ou pour le
transfert de compétences entre un développeur partant et son remplaçant.&lt;/p&gt;
&lt;p&gt;Enfin, un des avantages du Pair Programming qu'on ne cite jamais, mais qui
serait pourtant de nature à rassurer les responsables, est le gain de rigueur
et de focalisation dans le travail accompli. Un développeur qui paire sera
moins tenté d'aller consulter son facebook ou lire ses mails perso toutes les
cinq minutes. D'une part par respect pour son coéquipier, parce qu'il n'a peut
être pas envie d'étaler sa vie privée, et d'autre part parce que programmer en
binôme, c'est fixer mutuellement un cap et s'y tenir. C'est toujours beaucoup
plus engageant de se promettre conjointement avec un autre développeur
d'arriver au bout de cette fonctionnalité avant la pause déjeuner, que de se le
promettre juste à soi-même.&lt;/p&gt;
&lt;p&gt;Dans ces conditions, on peut se demander pourquoi tant de structures, même
celles qui se revendiquent agiles, n'adoptent pas le Pair Programming. Sans
doute est-ce une aberration dans un système encore dirigé par la sacro-sainte
mesure de la performance individuelle par rapport au temps de travail. Sans
doute aussi les décideurs voient-ils inconsciemment dans des coéquipiers des
gamins qui se font plaisir plutôt que des travailleurs.&lt;/p&gt;
&lt;p&gt;Au moins pourraient-ils, comme le préconise &lt;a href=&quot;http://martinfowler.com/bliki/PairProgrammingMisconceptions.html&quot; hreflang=&quot;en&quot;&gt;Martin Fowler&lt;/a&gt;, se donner la peine de l'essayer :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;My view is that you should try it and the team should reflect on whether
they feel they are more effective with pairing that without. As with any new
practice make sure you allow enough time so you have a good chance of crossing
the ImprovementRavine.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2009/09/19/Pair-Programming%2C-le-mouton-noir-des-pratiques-d-ing%C3%A9ni%C3%A9rie#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2009/09/19/Pair-Programming%2C-le-mouton-noir-des-pratiques-d-ing%C3%A9ni%C3%A9rie#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/442898</wfw:commentRss>
      </item>
    
  <item>
    <title>L'épanouissement tribal, promesse des méthodes agiles ?</title>
    <link>http://blog.infosaurus.fr/post/2009/09/16/Le-retour-%C3%A0-l-%C3%A9panouissement-social-tribal%2C-promesse-des-m%C3%A9thodes-agiles</link>
    <guid isPermaLink="false">urn:md5:d3ed48dedc4a4096df0c9aab3c4a3fc8</guid>
    <pubDate>Wed, 16 Sep 2009 20:03:00 +0200</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Méthodes et Entreprise</category>
        <category>Agile</category><category>Kanban</category><category>Management</category><category>Scrum</category>    
    <description>    &lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/3878896703_c6aa29f633.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.3878896703_c6aa29f633_sq.jpg&quot; alt=&quot;Totem&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Totem&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Le bonheur est à la mode. C'est un saint Graal que tout le monde, y compris
&lt;a href=&quot;http://www.lepost.fr/article/2009/09/14/1696547_le-bonheur-c-est-simple-comme-sarkozy-le-secret-de-l-abc-du-bonheur-national-brut.html&quot; hreflang=&quot;fr&quot;&gt;notre président&lt;/a&gt;, cherche à toucher du doigt en ces temps
difficiles. La France va mal, et il faut se doter des outils nécessaires pour
mesurer et améliorer le bien-être de ses citoyens.&lt;br /&gt;
Les récents cas de suicides au sein d'une célèbre entreprise de télécoms
témoignent plus précisément d'une zone sensible où beaucoup reste à faire en
matière de bonheur et d'épanouissement personnel : l'entreprise. En effet,
peu de salariés - même parmi les plus qualifiés comme les ingénieurs en
développement logiciel - peuvent se vanter de s'accomplir pleinement à travers
leur travail quotidien.&lt;/p&gt;
&lt;p&gt;Quelle réponse les méthodes agiles, et Scrum en particulier, peuvent-elles
apporter à ce douloureux problème ? En d'autres termes, quelle vision du
bonheur en entreprise avons-nous en mettant nos lunettes Scrum, comme diraient
certains ;) ?&lt;/p&gt;
&lt;p&gt;Tobias Mayer, scrum master et coach agile, a publié le mois dernier &lt;a href=&quot;http://agileanarchy.wordpress.com/2009/08/03/the-heart-of-scrum/&quot; hreflang=&quot;en&quot;&gt;un billet&lt;/a&gt; fort intéressant sur le sujet. A première vue, il semble y
être question du task board, parfois plus connu sous le pseudonyme de
Kanban : un objet qui, selon Tobias, est au coeur de la petite communauté
formée par l'équipe de développement. On peut même comparer le task board à un
lieu de culte sacré tant les fidèles se pressent aux rituels (les daily scrums)
qui s'y tiennent.&lt;br /&gt;
Mais le constat ne s'arrête pas là. Tobias file la métaphore et dévoile que les
méthodes agiles créent une organisation sociale similaire à celle d'une tribu,
car elles permettent à chaque membre de l'équipe de satisfaire pleinement son
besoin primaire de conversation, de débat, d'interaction. Et car la sensation
d'appartenance au groupe, la formation de codes et de valeurs communes qui
résultent du fonctionnement agile permettent de tirer le meilleur de chacun et
contribuent à mettre en mouvement une force vitale au sein du groupe
auto-organisé :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Scrum is about tribes, it is about building community. Each tribal
member needs a sense of belonging, a personal quest. Whole tribes need
gathering places, they need sacred objects, they need focus and they need
pulse. Scrum supports that way of being. The task board, and its emergent
environment provides the central life-force from which these things are
born.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;En somme, là où les méthodes de management de projet traditionnelles
s'acharneraient à brider nos instincts par la division des troupes, par une
bureaucratie implacable et l'introduction de nombreux tampons documentaires et
humains empêchant la communication (l'archétype étant les collaborateurs
séparés par des &lt;em&gt;cubicles&lt;/em&gt; et ne communiquant que par fiches de suivi
interposées), les méthodes agiles seraient un retour au naturel salutaire.
L'agilité serait le meilleur moyen de respecter nos gènes et ainsi d'obtenir
des résultats qu'aucun contremaître muni d'un fouet ou d'un dossier de
spécifications de 500 pages n'atteindrait à moyen terme.&lt;/p&gt;
&lt;p&gt;Je ne vois qu'une faille dans ce raisonnement ambitieux et brillant, et
c'est aussi celle qui me fait parfois douter que les méthodes agiles prendront
un jour le pouvoir sur la planète. Comment donner à tout le monde la
possibilité d'appliquer l'agilité ? Comment faire du type qui assure seul
la maintenance corrective d'une appli Cobol, une tribu Scrum ou XP ?
Comment insuffler cette force collective à l'équipe d'intérimaires qui assure,
micro-casques vissés sur les oreilles, le support technique niveau 1 d'une
plateforme applicative et ne communique que par l'intermédiaire de tickets avec
les gens du dessus ? Comment la batterie de développeurs chinois recopiant
3000 lignes de code à la minute peut-elle accéder à cette satisfaction
professionnelle ?&lt;/p&gt;
&lt;p&gt;L'épanouissement tribal est sans doute accessible, mais peut-être pas pour
tout le monde...&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2009/09/16/Le-retour-%C3%A0-l-%C3%A9panouissement-social-tribal%2C-promesse-des-m%C3%A9thodes-agiles#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2009/09/16/Le-retour-%C3%A0-l-%C3%A9panouissement-social-tribal%2C-promesse-des-m%C3%A9thodes-agiles#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/442303</wfw:commentRss>
      </item>
    
  <item>
    <title>Retour sur .NET RIA Services</title>
    <link>http://blog.infosaurus.fr/post/2009/09/12/Retour-sur-.NET-RIA-Services</link>
    <guid isPermaLink="false">urn:md5:2d3ec9d7bd6bf3046ddee4d3eada6652</guid>
    <pubDate>Sat, 12 Sep 2009 18:07:00 +0200</pubDate>
    <dc:creator>Guillaume</dc:creator>
        <category>Développement</category>
        <category>.NET</category><category>RIA Services</category><category>Silverlight</category>    
    <description>    &lt;p&gt;Il y a peu, nous avons décidé au sein de notre équipe de faire migrer un
projet en cours de développement de Silverlight 2 vers Silverlight 3, ce
dernier étant sorti en release officielle au courant de l'été. Contrairement à
ce que nous craignions, l'opération s'est bien passée, notamment grâce à cette
&lt;a href=&quot;http://www.itscodingtime.com/post/A-Silverlight-2-to-Silverlight-3-Checklist.aspx&quot; hreflang=&quot;en&quot;&gt;petite checklist&lt;/a&gt; bien utile. Une fois les tools Silverlight 3
installés, l'assistant de conversion de Visual Studio s'occupe d'à peu près
tout, sauf quelques mises à jour à faire si vous utilisez des services
WCF.&lt;br /&gt;
&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.infosaurus.fr/public/img/articles/silverlight-logo_1.jpg&quot;&gt;&lt;img src=&quot;http://blog.infosaurus.fr/public/img/articles/.silverlight-logo_1_t.jpg&quot; alt=&quot;Silverlight&quot; style=&quot;display:block; margin:0 auto;&quot; title=&quot;Silverlight&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Mais une autre question s'est posée à nous : fallait-il transformer nos
services WCF Silverlight 2 (assez lourds à manipuler et à mettre à jour) en
&lt;a href=&quot;http://www.nikhilk.net/NET-RIA-Services-Vision-Architecture.aspx&quot; hreflang=&quot;et&quot;&gt;RIA Services&lt;/a&gt; ? En effet ce nouveau framework applicatif
paraissait contenir plein de bonnes surprises pour nous faciliter la vie.
Utilisant pour prendre la décision une méthode un peu débile mais qui marche, à
savoir un tableau avec une colonne + et une colonne -, voici ce que nous avons
obtenu :&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Du côté des avantages :&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;+ Un découpage clair des couches et un système de DomainContext qui peut se
marier avec du MVVM, du MVC ou même du MVP (solution que nous avions
retenue).&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;+ Les classes clientes des services côté Silverlight sont automatiquement
générées lors du build des services, pas de référence de service à ajouter ou
mettre à jour contrairement à du WCF classique. Lors du passage sur un serveur
d'intégration continue ou de recette, on s'ôte aussi un gros poids puisque la
mise à jour des références vers le nouvel emplacement des services n'a pas lieu
d'être.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;+ Tout un tas de facilités introduites aussi bien au niveau de
l'interrogation des services que de la mise à jour des entités.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;+ Exceptions de services WCF mieux gérées qu'avec Silverlight 2 (le retour
d'exceptions du service vers le client Silverlight n'était tout simplement pas
géré) et Silverlight 3 (où il faut &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd470096%28VS.96%29.aspx&quot; hreflang=&quot;en&quot;&gt;surcharger un comportement&lt;/a&gt; pour générer le bon code d'erreur à
renvoyer au client).&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;+ Meilleure prise en charge des rôles et droits utilisateur...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Les inconvénients :&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;- RIA Services est encore en CTP, pour une sortie pas prévue avant 2010
(!)&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;- Il faut une &lt;a href=&quot;http://forums.silverlight.net/forums/t/121056.aspx&quot; hreflang=&quot;en&quot;&gt;petite bidouille&lt;/a&gt; pour installer RIA Services sur un Visual
Studio français.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;- Une testabilité ... à tester. Le mocking des DomainServices n'a pas l'air
évident même si Nikhil Kothari a proposé une solution &lt;a href=&quot;http://www.nikhilk.net/NET-RIA-Services-ViewModel-Pattern-2.aspx&quot; hreflang=&quot;en&quot;&gt;sur son blog&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;- Mauvaise intégration avec ReSharper : il faut inclure les classes
clientes générées par RIA Services dans le projet Visual Studio sinon ReSharper
ne retrouve pas ses petits.&lt;/p&gt;
&lt;p&gt;Tout compte fait, ça a beau ne pas être une version finale, les avantages et
les gains de temps induits sont tels qu'on ne voit pas comment trouver le
courage de s'en passer ! Reste le problème de la stabilité d'une CTP et de
la nécessité de repenser les services, qui peut, on le comprend, en rebuter
certains. Toutefois, dans un projet très peu critique comme le nôtre, le risque
semble en valoir la chandelle.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.infosaurus.fr/post/2009/09/12/Retour-sur-.NET-RIA-Services#comment-form</comments>
      <wfw:comment>http://blog.infosaurus.fr/post/2009/09/12/Retour-sur-.NET-RIA-Services#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.infosaurus.fr/feed/atom/comments/441076</wfw:commentRss>
      </item>
    
</channel>
</rss>