<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="/style/rss.xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <atom:link href="gemini://sroccaserra.fr/rss.xml" rel="self" type="application/rss+xml" />
        <title>Apprendre + Équipe = Programmes</title>
        <link>gemini://sroccaserra.fr</link>
        <description>
            Des notes sur ce que j'observe dans les métiers liés à la
            conception de logiciels
        </description>
        <image>
            <url>gemini://sroccaserra.fr/favicon.ico</url>
            <link>gemini://sroccaserra.fr</link>
        </image>

        <item>
            <title>Comment j'ai appris mon métier, comment j'ai progressé ?</title>
            <link>gemini://sroccaserra.fr/articles/2026-02-18_comment-j-ai-appris-mon-metier.gmi</link>
            <description>Hier cette question était posée sur FramaTeam :

&gt; Comment avez-vous appris votre savoir, comment avez-vous progressé ?

Ouf ! Super question ! Je ne peux pas y répondre complètement, mais j&apos;essaie quelque chose.

## Découverte

Tout à commencé pour moi par la découverte du Basic et du Logo sur MO5 en centre aéré au primaire. On dessinait des cercles et des motifs sur un écran monochrome, c&apos;était rigolo.

Pendant cette période, j&apos;étais déjà interessé. Au début c&apos;était surtout physique, les couleurs bleues intense de l&apos;écran du MO5, le côté magique du crayon optique posé sur l&apos;écran cathodique plein d&apos;électricité statique, et toutes ces touches je trouvais ça chouette.

Au lycée, j&apos;ai bidouillé sur calculatrice graphique en lisant le manuel, et cours de Pascal en terminale, c&apos;était un monde calme et à part. Et j&apos;avais aussi un ami qui explorait, donc on pouvait s&apos;inspirer de ce que l&apos;autre faisait.

En prépa, j&apos;ai bidouillé sur HP 48 en RPL, un mini Forth. J&apos;ai fini par faire une quine sans savoir ce que c&apos;était, mon idée était de faire un programme qui se rajouterait lui-même à la fin d&apos;un autre programme (le RPL est un langage concaténatif, ça aide). J&apos;ai bien lancé la quine pour vérifier, mais je n&apos;ai jamais activé la réplication à la fin des autres programmes, par peur que ça fonctionne. Il y avait un côté puzzle ludique.

Avec ces calculatrices graphiques, je pouvais passer du temps à chercher les instructions qui pourraient améliorer mes programmes dans leurs épais manuels. C&apos;était un peu comme une chasse au trésor, qui continue encore aujourd&apos;hui. C&apos;est le premier élément de réponse à la question.

En école d&apos;ingénieur, j&apos;ai eu des cours de C, C++ et Java, et des cours d&apos;algorithmique. J&apos;ai reçu des bases classiques avec de bons profs, mais je n&apos;étais pas prêt à les apprécier, j&apos;ai peu de souvenirs. Autre point,  j&apos;étais dans une école généraliste donc la programmation ne constituait pas la majorité de l&apos;enseignement. Je pense que cette étape a été importante cependant, j&apos;y ai été exposé à beaucoup de concepts fondamentaux que j&apos;ai pu explorer plus tard facilement grâce à ces cours. Je pense qu&apos;une certaine familiarité et une structuration de mes idées sur la programmation ont été installées et j&apos;en suis reconaissant. Ça m&apos;a donné une situation, au sens de m&apos;apprendre à me situer.

## Premier job

Premier boulot, premiers apprentissages avec les collègues. On ne faisait pas de pair programming, mais on discutait, et je faisais relire mon code.

C&apos;est aussi les premières explorations du code de quelqu&apos;un d&apos;autre. Ces explorations m&apos;ont permis de progresser : essayer de comprendre, avec un papier et un crayon = une nouvelle sorte de chasse au trésor. On peut même faire des cartes.

Et aussi, premiers livres. Le dev senior de l&apos;équipe (coucou Olivier !) me passe les bouquins Effective C++, de Scott Meyers. C&apos;est un peu une révélation pour moi : les livres, en expliquant des points techniques du langage, dévoilent énormément de pratiques de dev. très mémorables. Par exemple, dans l&apos;Item 18: &quot;Make interfaces easy to use correctly and hard to use incorrectly&quot;, le conseil suivant pour implémenter les opérateurs classiques de ses propres types :

&gt; When in doubt, do as the ints do.

Avec à chaque fois, une explication des conséquences de le faire ou de ne pas le faire. J&apos;ai lu ces livres du début à la fin, passionné par la découverte d&apos;un nouveau niveau de finesse que je n&apos;imaginais pas. Wow! Je commence à comprendre que je n&apos;aurai jamais fini d&apos;apprendre mon métier.

Il y avait aussi le classique Design Patterns, je l&apos;ai trouvé intéressant mais il ne m&apos;a pas marqué autant.

Ensuite le même collègue me passe le bouquin Extreme Programming Explained, ça me donne envie de travailler comme ça. J&apos;essaie un peu, mais seul ce n&apos;est pas simple. Patience, il me faudra encore environ cinq ans avant de trouver des gens qui pratiquent XP.

# Deuxième job

Dans mon deuxième job, je rencontre une bande de fous qui font des jeux vidéos, et là c&apos;est l&apos;effervescence. Je suis à nouveau le plus mauvais de l&apos;équipe (en tout cas c&apos;est mon opinion), ce qui est une super position pour apprendre. C&apos;est même un conseil qu&apos;on voit partout sur Internet maintenant.

Dans un open space, je suis au milieu d&apos;experts en 3D qui ont écrit des moteurs 3D ou des drivers de carte graphique, d&apos;experts réseaux, de personnes qui ont codé des jeux en assembleur dans les années 90 (coucou Fabrice). Les échanges sont permanents, et cette équipe fonctionnait comme un genre d&apos;organisme qui essaie de s&apos;améliorer en permanence. Les infos circulaient à grande vitesse entre personnes très curieuses, on passait régulièrement notre temps à former des groupes de deux et à discuter en pointant du doigt sur notre écran. Quelle chance. Et on échangeait aussi avec les graphistes et les game designers : ce n&apos;était pas que de la programmation. Wow!

Et là encore, des livres. Il y avait une bibliothèque bien fournie, et un budget open bar pour faire commander des livres. Le livre qui m&apos;a le plus marqué est The Pragmatic Programmer. Il couvre presque tous les pans du métier, et est agréable à lire. Une mine d&apos;or, je le recommande encore aujourd&apos;hui.

Un autre livre qui m&apos;a marqué est Programming in Lua. Ce livre décrit un langage très petit, et montre comment on peut étendre le langage pour l&apos;adapter à ses besoins à partir de principes très simples. Par exemple voilà comment fournir un set alors qu&apos;il n&apos;y a pas de structure de données &quot;set&quot; dans le langage :

```lua
function Set (list)
  local set = {}
  for _, l in ipairs(list) do set[l] = true end
  return set
end

reserved = Set{&quot;while&quot;, &quot;end&quot;, &quot;function&quot;, &quot;local&quot;}
```

Ce livre m&apos;a montré :
* Que tous les langages ne se ressemblent pas
* Que le sens du progrès n&apos;est pas nécessairement d&apos;ajouter de la complexité
* Comment on peut rendre n&apos;importe quel langage expressif à partir de principes simples

C&apos;est aussi là que j&apos;ai appris le Web, en faisant... du Smalltalk. On parlait souvent de ce langage avec un collègue (coucou Ludo), et à l&apos;époque un framework Web &quot;révolutionnaire&quot; était sorti. Il existe encore aujourd&apos;hui :

=&gt; https://github.com/seasidest/seaside Seaside

Voilà une autre façon de progresser : essayer des choses radicalement différentes. Ce que j&apos;ai appris en Smalltalk a changé ma façon de voir un programme. Ce n&apos;est plus une liste de fichiers, mais des classes et des méthodes qu&apos;on peut browser, et modifier en live.

Dans la même idée, le collègue qui m&apos;avait montré Smalltalk m&apos;a montré Emacs. Et donc je me suis trouvé projeté dans Emacs Lisp, et dans cette éditeur de texte qui peut s&apos;explorer et se modifier lui même. Wow!

## À Suivre ?

Voilà le début. Et vous, comment avez-vous appris votre savoir, comment avez-vous progressé ?
            </description>
            <pubDate>2026-02-18</pubDate>
            <guid>gemini://sroccaserra.fr/articles/2026-02-18_comment-j-ai-appris-mon-metier.gmi</guid>
        </item>
        <item>
            <title>Météo du jour - Coder en pâte à modeler</title>
            <link>gemini://sroccaserra.fr/billets/2026-02-17_coder-en-pate-a-modeler.gmi</link>
            <description>Bonjour, c&apos;est la météo du jour.

```
* Caen :      ☀️    +7°C
* Marseille : ☀️    +10°C
* Lille :     🌦    +4°C
* Paris :     ⛅️    +7°C
* Toulouse :  ☁️    +10°C
```


En ce moment il fait froid à Caen, mais avec du soleil. Presque comme à Marseille, où il fait moins froid.

----

Aujourd&apos;hui, je pense à une compétence particulière que développe le fait de coder avec des tests automatisés.

Coder avec des tests automatisés développe la capacité à créer un design comme avec de la pâte à modeler. On ajoute progressivement de la matière (du code) et on lui donne la bonne forme, un problème à la fois. Cette capacité est ensuite utile, même quand on ne développe pas avec des tests automatisés.

Donc à chaque fois que je peux travailler avec des tests automatisés, je le fais, car je trouve cette manière de concevoir du logiciel agréable et efficace.

Mais quand je ne peux pas utiliser de tests automatisés, je peux quand même utiliser cette façon de concevoir. Mes compétences se transposent en grande partie. La question qui se pose alors, et qui se pose en réalité quelle que soit la façon de coder, c&apos;est : &quot;comment est-ce que je peux vérifier que ça marche ?&quot; Si je peux facilement vérifier que mon programme fonctionne, je peux coder en pâte à modeler.

J&apos;essaie alors de trouver la manière la plus rapide de vérifier que ça marche. Lancer l&apos;application ? Pourquoi pas, si j&apos;ai la possibilité de faire un live reload. Mais n&apos;y a-t-il pas plus rapide ? Je peux parfois faire une requête SQL, ou grep sur la sortie standard. Je note que en faisant ça, j&apos;ai un peu commencé à automatiser la vérification. Un premier pas vers l&apos;automatisation des tests ?

Et vous, est-ce que vous codez en pâte à modeler ? Comment est-ce que vous vérifiez que ça marche ?

Voir aussi:

=&gt; https://www.geepawhill.org/2021/09/29/many-more-much-smaller-steps-first-sketch/ Many More Much Smaller Steps
            </description>
            <pubDate>2026-02-17</pubDate>
            <guid>gemini://sroccaserra.fr/billets/2026-02-17_coder-en-pate-a-modeler.gmi</guid>
        </item>
        <item>
            <title>Notes sur Claude Code</title>
            <link>gemini://sroccaserra.fr/articles/2026-02-14_j-ai-teste-claude-code.gmi</link>
            <description>J&apos;ai testé Claude Code, et j&apos;ai pris ces notes à cette occasion.

Disclaimer : ce sont mes notes sur un projet greenfield de 2000 lignes de code écrit en deux jours environ. Ces notes ne sont pas généralisables.

Note au passage : si ce genre de sujets vous intéresse et que vous souhaitez avoir une vision globale autours de ces questions, la conf &quot;L&apos;humanité a-t-elle les moyens de s’offrir l’IA ?&quot; de Tristan Nitot à la School of Product 2025 est très bien.

=&gt; https://www.youtube.com/watch?v=oXQZ8AVNxnQ L&apos;humanité a-t-elle les moyens de s’offrir l’IA ?

## Mes notes

### Flow

Good : aucune difficulté de prise en main pour un dev senior. On comprend la plupart des choses faites par l’outil, on peut lire les commandes shell utilisées. Impression : peu ou pas de courbe d’apprentissage quand on connait bien le métier de dev, le shell, les tests, les patterns.

Good : je dis à l’outil de faire, c’est l’outil qui tape. Super reposant. Les changements fatigants et rébarbatifs deviennent plaisants car c’est l’outil qui tape. On peut aller beaucoup plus loin en terme de qualité, la facilité d’usage enlève les freins à l’action. Déléguer le clavier et les implémentations bas niveau nous laisse aussi plus d’énergie pour le nommage et les améliorations. Mais : voir aussi risque d’addiction dans la section warnings ci-dessous.

### Agents &amp; Craft

Flow qui fonctionne : faire de petites étapes, tester et commiter à chaque fois. Good : l’outil lance automatiquement les tests qu’il trouve pour vérifier ce qui est tapé, et en génère sur le modèle de ce qui existe. C’est très compatible TDD, on peut appliquer tout ce qu’on sait faire : un changement complexe rendu super simple par une succession de petites étapes super safes. Je dirais même plus, dans mon essai, guider l’outil par une succession de petites étapes claires a donné des résultats remarquables. J’ai eu quasiment systématiquement ce que j’ai demandé, fait correctement et exécuté en 15 s. à 30 s. environ (note : mesures réelles à faire). Il est donc sans doute mieux de guider à la Craft que de faire une spec géante de haut niveau ? IMHO, Craft FTW!

Toujours garder un œil sur la taille des fonctions, sur la structure : l’outil peut les améliorer, il peut même auditer la base de code, trouver les défauts et les corriger, mais il ne le fera pas de lui même si on ne lui demande pas. Il est aussi intéressant de guider la correction des défauts en donnant des directives de haut niveau (niveau archi logicielle). Craft, Boyscout Rule, DRY, YAGNI, etc., à nous de guider.

De mon expérience, les réflexes des crafteux·ses restent très pertinents : le cycle &quot;fait ce changement, vérifie le, simplifie ceci, fait cet autre changement, vérifie le, simplifie cela&quot;, etc. permet de garder le contrôle sur la qualité de ce qui est produit tout au long du dev. Ce qui veut dire qu&apos;à tout moment on peut livrer. Plutôt que de lui donner une spec géante, puis de passer beaucoup de temps a simplifier un truc devenu trop énorme et ingérable, et puis on doit livrer donc tant pis et la simplification passe à la trappe.

Voir les warnings sur le prix ci-dessous, car tout ça incite à une utilisation de l’outil “open bar”.

### Agents &amp; vérifications automatiques

Intéressant : l’outil utilise beaucoup GNU CoreUtils, un peu ce que j’aurais fait. Par ex. fait un `grep -rl &quot;&amp;apos;&quot;` au début pour trouver les fichiers à modifier, et à la fin pour vérifier que tout est modifié. Peut utiliser `grep -rn &quot;&amp;apos;&quot;` pour trouver les lignes à éditer. Utilise aussi régulièrement `find` et `sed`. C’est des choses qu’on peut faire nous aussi, autant apprendre ça en passant. D’autant que si vous avez un historique de shell un peu long, vous pouvez réutiliser ce genre de commandes et ne pas les retaper à chaque fois.

Opportunités : quand l’outil vérifie le résultat de ce qui est tapé, c’est automatiquement, on voit des appels shell. Donc on peut lui dire “sauve cette vérification dans un script de test”, ou dans un script d’analyse. Ça c’est cool car ensuite on peut lire le script de test, le comprendre, et l’utiliser soi-même ou l’intégrer dans les suites de tests autos.

### Docs

Good : Ajouter une ADR? Super facile, enlève toute friction. L’outil la rédige au bon endroit, à partir d’une analyse ou d’un commit.

Question : dans les revues, l’outil semble répéter ce qu’il a rédigé dans les commits (?)

Good / Meh : génère des docs de 500 lignes tout seul. Les docs sont de bonne qualité en général, et l’outil peut les mettre à jour à la demande, voir met à jour à l’occasion d’un changement (non systématique). Tendance à dupliquer, des infos se retrouvent dans plusieurs docs voir dupliquées dans le même doc. Lors des mises à jour, ne met pas toutes les duplications à jour. Aussi, vérifier tous les numéros de section, qui sont souvent bons mais pas tout le temps. Et vérifier tous les chiffres, on voit des témoignages de données inventées. Fournir des outils pour générer les chiffres. Autre point : quand on lui demande de mettre à jour plusieurs fois une doc, au bout d’un moment la doc devient saturée d’infos. Et quand on demande à l’outil de refaire la doc from scratch, la doc résultat est toujours bonne, mais change sur plusieurs aspects (sections différentes, ou notation sur 10 qui devient sur 5 ou l’inverse).

Conséquence : d’un côté les docs générées incluent plein d’infos utiles qu’on n’aurait pas pensé à inclure, mais si on veut des docs avec les infos les plus importantes bien visibles, sans redondance et avec le bon niveau d’information, ça demande pas mal de travail de simplification et de restructuration.

### Warnings

Meh : commit régulièrement tout seul au bout d’un moment alors que j’ai mis dans la conf de toujours demander avant de commiter.

Pb : très addictif, on n’arrive plus à s’arrêter d’autant qu’il y a un genre d’”émulation”, comme l’outil ne faiblit pas on est amené à continuer sans cesse par mimétisme (c.f. article récent sur le risque de burnout avec ce genre d’outil).

Warning : on n’a plus envie de se mettre à réfléchir sur le “how”, on est addict au “what”, surtout sur les petits nettoyages barbants ou les nouvelles évolutions. On s’entraine à ne plus faire les tâches barbantes, qui sont perçues comme encore plus barbantes.

Warning : on a tendance à dégainer l’outil dès qu’on doit réfléchir plus de 3 secondes. Risque fort de perte de compétence / syndrome d’imposteur auto réalisant. ⇒ continuer à faire régulièrement soi-même des tâches difficiles qui nécessitent de réfléchir longtemps et avec risque d’erreur et de tâtonnement si on veut ne pas perdre la main.

Quand on fait des changements en dehors de l’outil, l’outil les rate parfois (sans doute une histoire de cache). Au bout de plusieurs fois on a envie de tout faire depuis l’outil, donc d’utiliser l’outil encore plus.

Prix = ??? facile de dépenser $ 50 à $ 100 par jour avec l’API Amazone Bedrock (si la commande /cost fonctionne). C’est cette utilisation “open bar” qui est “efficace”. Si j’ai bien vu, un usage de l’outil un peu efficace est de l’utiliser tout le temps. S’il faut se restreindre, avec par exemple des temps de “refroidissement” pour attendre que notre crédit ou quota se recharge, on va avoir tendance à faire du stop and go qui pourrait être contre productif.

Warning : la longueur de réflexion semble augmenter avec la taille du projet, mais je ne l’ai utilisé que sur ~2000 lignes de code.

Warning : il y a un côté Reine rouge. Le système induit par l’outil nous invite à courir de plus en plus vite pour rester au même endroit, alors que certains processus de pensée nécessiteraient de faire une pause pour corriger la direction. Par exemple, est-ce que je suis en train de faire la bonne chose ? Est-ce que je suis en train de la faire de la bonne façon ? Quel est le but que faire cette chose me permet d’atteindre ? Est-ce que ce but est raisonnable ? Si on n’a jamais le temps d’avoir ce genre de réflexions, on risque d’être très efficace pour apporter la bonne solution au mauvais problème. Avec ces outils qui accélèrent, charge à l’individu de s’astreindre à faire des pauses, et à laisser à sa pensée le temps de mûrir s’il veut résister à l’injonction d’emballement. Charge à l’individu de cadrer son propre usage de l’outil. Or, en règle général, le système mange l’individu au petit déjeuner. Remember, fix the system, not the people.

Note : Mon premier réflexe à été de me dire que j’avais “gagné du temps”. Or IMHO on ne “gagne” pas de temps, i.e. on n’économise pas de temps de travail. Le temps “libéré” n’est pas libéré, il est utilisé à faire plus, par peur de la compétition, à tort ou à raison. Donc au mieux on fait beaucoup plus en le même temps, voire on travaille plus de temps qu’avant par effet d’entrainement. Un genre d’effet rebond ?

Voir aussi :

=&gt; https://hbr.org/2026/02/ai-doesnt-reduce-work-it-intensifies-it
=&gt; https://techcrunch.com/2026/02/09/the-first-signs-of-burnout-are-coming-from-the-people-who-embrace-ai-the-most/

---

## Bonus : Explorer les commandes utilisées par Claude

Comme l&apos;outil garde les conversations dans des fichiers jsonl, je les ai explorés avec jq vite fait. On peut donc apprendre à faire comme Claude.

### Outils les plus utilisés

Par exemple, je peux voir quels outils il utilise le plus, sur une journée environ, sans surprise le top 10 (make because j&apos;ai fait du C ce jour là), GNU CoreUtils est très utilisé :

```
$ find ~/.claude/projects/-some-path/ -type f \
    | xargs jq -f jclaude.jq | cut -d&apos; &apos; -f1 | sort | uniq -c | sort -n
      1 &quot;awk
      1 &quot;./build/convert&quot;
      1 &quot;ctags
      1 &quot;perl
      1 &quot;pwd&quot;
      1 &quot;rmdir
      1 &quot;scripts/analyze-function-lengths.sh
      2 &quot;~/bin/gemtext_to_html
      2 &quot;./scripts/analyze-function-lengths.sh&quot;
      2 &quot;touch
      2 &quot;tree
      3 &quot;chmod
      3 &quot;rm
      3 &quot;./scripts/test_dependency_tracking.sh&quot;
      4 &quot;./build/gemtext_to_html_example
      4 &quot;./scripts/test_convert.sh&quot;
      5 &quot;cloc
      7 &quot;mkdir
      8 &quot;./scripts/analyze-function-lengths.sh
     14 &quot;cat
     14 &quot;find
     14 &quot;ls
     18 &quot;wc
     26 &quot;./build/convert
     27 &quot;echo
     31 &quot;grep
     32 &quot;sed
    227 &quot;make
    473 &quot;git
```

Script jclaude.jq pour filtrer le jsonl :

```jq
.message?.content?[]?
| select(.type? == &quot;tool_use&quot;)
| .input?.command?
| select( . != null)
```

### Lister les usages de sed

Commande :

Ensuite, toujours avec jq, j&apos;ai exploré les commandes sed et find pour piquer des astuces, mais de ce que j&apos;ai vu c&apos;est du classique, `sed -i` ou `find ... | exec ...`. Le pattern simple mais sympa que j&apos;ai trouvé et qui ressemble à ce que je fais, c&apos;est :

* faire un `grep -rn toto` pour visualiser l&apos;étendue du changement
* faire un `grep -rl toto | sed -i &apos;s/toto/tata&apos;` pour faire le changement
* faire un `grep -rn toto` à nouveau pour vérifier le changement
* of course, lancer les tests pour vérifier qu&apos;on n&apos;a rien cassé.

Commande bash:

```
$ find ~/.claude/projects/-some-path/ -type f \
    | xargs jq -r -f jclaude.jq
```

Script jclaude.jq :

```jq
.message?.content?[]?
| select(.type? == &quot;tool_use&quot;)
| .input?.command?
| select( . != null)
| select( . | startswith(&quot;sed&quot;))
| &quot;\(.)\n&quot;
```
            </description>
            <pubDate>2026-02-14</pubDate>
            <guid>gemini://sroccaserra.fr/articles/2026-02-14_j-ai-teste-claude-code.gmi</guid>
        </item>
        <item>
            <title>Météo du jour - Un frein aux nouvelles pratiques ?</title>
            <link>gemini://sroccaserra.fr/billets/2025-08-28_un-frein-aux-nouvelles-pratiques.gmi</link>
            <description>Bonjour, c&apos;est la météo du jour.

```
Caen:      ☀️   +14°C
Lille:     ⛅️   +16°C
Marseille: 🌩   +24°C
Paris:     🌦   +18°C
Toulouse:  🌦   +20°C
```

En ce moment il fait beau à Caen, profitons en !

----

Ce matin, j&apos;ai lu un post sur LinkedIn qui listait des raisons classiques pour ne pas écrire de tests unitaires, par exemple :

* Je n&apos;ai pas l&apos;intention de rester sur ce projet, et n&apos;aurai pas à subir les conséquences
* Les bugs en prod c&apos;est mon kif, surtout avec le client au bout du fil un samedi
* J&apos;adore le debugging, surtout quand je dois rafraîchir le navigateur et lire mes console.log dans des tonnes de logs
* etc.

C&apos;est intéressant comme partage, et j&apos;ai pu (rarement) l&apos;entendre, mais d&apos;une part je trouve les formulations un peu accusatrices. Elles me donnent l&apos;impression que des individus se braqueraient de manière irrationnelle ou provocatrice contre une bonne pratique qui n&apos;attendrait qu&apos;à être appliquée. Et d&apos;autre part, en tant que Tech Lead ou Coach Technique, même si j&apos;entends parfois des remarques qui peuvent ressembler à ce qui est dit, ce que j&apos;observe en majorité est assez différent.

Le frein le plus important que j&apos;observe là où j&apos;interviens, c&apos;est en extrapolant un peu pour rendre visible certains points :

&gt; On voit bien comment faire sur de petits exercices mais on ne sait pas faire sur notre code. Et comme on est déjà très stressé·es par les deadlines qui s&apos;enchaînent et qu&apos;on n&apos;a pas assez de temps pour faire tout le travail qu&apos;on a déjà à faire, on se sent débordé·es et c&apos;est très compliqué pour nous d&apos;expérimenter une nouvelle pratique dont on ne sait pas si elle va fonctionner dans notre contexte ni en combien de temps.

Dans cette situation c&apos;est psychologiquement très compliqué de faire l&apos;investissement collectif d&apos;apprendre une nouvelle pratique, d&apos;autant plus que souvent personne n&apos;a vu faire et personne ne sait faire.

De mon point de vue le problème est systémique et concerne plus que l&apos;équipe, et la réaction de l&apos;équipe est plutôt à interpréter comme &quot;on est en mode survie, et donc on préfère fonctionner comme on sait faire car on n&apos;est pas certains de pouvoir survivre d&apos;une autre façon&quot;. Avant de changer quelque chose c&apos;est un point à bien évaluer et à prendre en compte car si on ne change pas le contexte de l&apos;équipe, on risque d&apos;ajouter du stress en plus de celui déjà présent.

Ça m&apos;évoque une citation de Virginia Satir que j&apos;aime relire de temps en temps :

&gt; I have such respect for the status quo because I know that it’s in the status quo where people are sensing the familiar, and therefore they are feeling they can survive. Whatever the price is, I can still survive. No matter how many times I need to get beaten, or how much I can’t eat, or whatever: I’m surviving. And if I don’t know what else is around, I’m going to cling to that.
&gt;
&gt; When we start in the process of change, we encounter resistance. Resistance is our friend. Resistance says: I want to live. To break down resistance is to court death. So what do we want to do with resistance? First of all to hear it respectfully. This is the personality or ourselves telling us: we don’t know any other way to live yet. And therefore we want to respect this. As leaders of the change process, we want to find a way of encompassing resistance as a survival factor, and move into some new way to survive without the resistance.

Quand je prends en charge un process de changement, j&apos;ai la responsabilité de proposer et d&apos;expliquer une nouvelle façon de fonctionner. Si des personnes refusent le changement, en général elles ne le font pas par provocation ni par manque de rationalité. En tant que personne qui propose le changement, c&apos;est ma responsabilité d&apos;écouter ces freins et de proposer quelque chose qui convient au contexte et aux personnes. Parfois ça demande du temps et beaucoup de curiosité de ma part.

S&apos;ajoute à ça le fait qu&apos;apprendre une nouvelle pratique, comme l&apos;écriture de tests unitaires par exemple, s&apos;inscrit dans une liste de priorités : si on investit collectivement du temps et de l&apos;énergie dans cet apprentissage, ça nous retire du temps pour faire autre chose, qui est potentiellement tout aussi important. Donc même si personnellement je pense que c&apos;est très souvent une bonne idée d&apos;investir ce temps d&apos;apprentissage, c&apos;est aussi ma responsabilité d&apos;expliquer pourquoi je pense que c&apos;est une bonne idée, et d&apos;aider l&apos;équipe à choisir si cet investissement est opportun pour elle maintenant, en fonction de tout ce qu&apos;elle a à faire par ailleurs. Souvent, le ressenti collectif c&apos;est que &quot;on n&apos;a jamais le temps.&quot; Mais même si le ressenti se ressemble souvent, les raisons de ce ressenti ne sont pas toujours les mêmes. Alors peut-être, par exemple, questionner pourquoi dans ce contexte donné on n&apos;a jamais le temps ? Ou bien tenter de faire entrer dans l&apos;équation le coût de ne pas poser de tests unitaires ?

Pour finir, en tant que coach ou tech lead, quand je vois l&apos;équipe au complet, incluant le management et le pouvoir de décision, décider d&apos;améliorer leurs pratiques et d&apos;y consacrer du temps, mon intervention se passe beaucoup mieux de tous les points de vue. Même si parfois on ne peut pas faire mieux qu&apos;une initiative individuelle qu&apos;on peut réussir à rendre contagieuse grâce à de bons résultats, en mode bottom-up.

Pour ces raisons, je préfère m&apos;intéresser à la question de qu&apos;est-ce qui freine au niveau collectif ou systémique, plutôt que de recenser des freins individuels comme &quot;Les bugs en prod c&apos;est mon kif, surtout avec le client au bout du fil un samedi&quot;.

Fin.

=&gt; https://www.youtube.com/watch?v=tnXY_aetEnU The Process of Change - Virginia Satir
=&gt; https://www.linkedin.com/posts/blambeau_softwareengineering-testing-activity-7366340021504688128-dFp4 Le post LinkedIn en question
            </description>
            <pubDate>2025-08-28</pubDate>
            <guid>gemini://sroccaserra.fr/billets/2025-08-28_un-frein-aux-nouvelles-pratiques.gmi</guid>
        </item>
        <item>
            <title>Météo du jour - Déléguer son temps de pensée ?</title>
            <link>gemini://sroccaserra.fr/billets/2025-08-19_meteo_thinking_time_delegation.gmi</link>
            <description>Bonjour, c&apos;est la météo du jour.

```
Caen:      🌧  +24°C
Lille:     ☀️  +29°C
Marseille: ☀️  +31°C
Paris:     🌩  +29°C
Toulouse:  ☁️  +28°C
```

En ce moment, il fait chaud mais moins que la semaine dernière. Et on n&apos;est pas mal à Caen, avec cette bonne fraîcheur que la France nous envie.

----

Et ce matin en lisant un thread de collègues, j&apos;ai pensé au point suivant : quand on utilise la gen AI pour écrire du code, ou pour comprendre du code, alors on délègue du “thinking time per line of code” à la machine, à une techno qui a un taux d’erreur non négligeable.

Ce qui m&apos;a fait penser que : vérifier ce qu’a fait la machine devient d’autant plus important. Ici, des pratiques comme TDD ou des tests automatisés, des pratiques craft, enfin tout ce qui peut nous aider habituellement à vérifier que le code fonctionne comme attendu va rester très utile.

Cette notion de &quot;tinking time per line of code&quot; me rappelle aussi que, avant la gen AI je trouvais déjà que dans mes équipes, moi y compris, on avait un &quot;thinking time per line of code&quot; beaucoup trop bas et qu’on gagnerait à l’augmenter. Je ne sais pas évaluer l’influence de cette délégation supplémentaire sur ce point, elle dépend de la qualité du &quot;thinking time per line of code&quot; de la gen AI (qui bien sûr ne pense pas, mais qui délègue à son tour au thinking time qui a été dépensé pour créer ses données d’entraînement).

Bien sûr, si on délègue son temps de pensée sur l&apos;écriture des lignes de code, ça nous libère du temps de pensée pour autre chose. On peut donc y trouver son compte. Le point qui m&apos;intéresse ici est que ce temps de pensée qu&apos;on a gagné pour écrire notre code nous obligera probablement à utiliser ensuite la gen AI pour lire notre code.

Alors : avec cette délégation on se crée une dépendance à l&apos;outil gen AI. Outil dont je ne sais pas prédire si les montages financiers exotiques qui soutiennent sa croissance hors du commun sont pérennes, et dont je ne sais pas prédire l’évolution de la tarification. S’ajouter cette dépendance c’est faire un pari sur l’avenir ⇒ d’un point de vue stratégie d’entreprise ça me donnerait envie d’évaluer les risques d’un éclatement de bulle ou d’une augmentation forte du tarif. Ce que je ne sais pas faire. Si vous avez vu passer des évaluations de ce genre de risques ça m’intéresse.

Ensuite il y a les aspects environnementaux et sociaux qui me posent question, mais j’ai l’impression que c’est compliqué d’en parler car ce que je lis n’est pas optimiste et est clivant, et je n’ai pas l’énergie pour en discuter ici.

----

Bonus : je pense aussi à l&apos;essai &quot;Programming as Theory Building&quot; :

&gt; Peter Naur’s classic 1985 essay “Programming as Theory Building” argues that a program is not its source code. A program is a shared mental construct (he uses the word theory) that lives in the minds of the people who work on it. If you lose the people, you lose the program. The code is merely a written representation of the program, and it’s lossy, so you can’t reconstruct a program from its code.
            </description>
            <pubDate>2025-08-19</pubDate>
            <guid>gemini://sroccaserra.fr/billets/2025-08-19_meteo_thinking_time_delegation.gmi</guid>
        </item>
        <item>
            <title>Météo du jour - Souvenirs de David Lynch</title>
            <link>gemini://sroccaserra.fr/billets/2025-07-24_meteo.gmi</link>
            <description>Bonjour, c&apos;est la météo du jour.

```
Caen :      ⛅️  +18°C
Lille :     🌫  +15°C
Marseille : ☀️  +20°C
Paris :     🌦  +16°C
Toulouse :  ☁️  +17°C
```

Aujourd&apos;hui, on aura enfin une température de saison. D&apos;aucun diraient qu&apos;il fait un peu froid, mais souvenons nous que dans les années 90 ça aurait été une journée tout à fait normale. Nos habitudes ont changé.

----

Ce matin, je pense à David Lynch. Ce sont ses billets météo quotidiens qui m&apos;ont donné envie de le copier, et de partager mes idées du jour sous prétexte de donner la météo. Et puisque je pense à David Lynch, je me rappelle de certaines autres de ses idées qui ont résonné pour moi.

&gt; You&apos;ve got this idea, and you can see it and hear it and feel it and know it.  Now, let&apos;s say you start cutting a piece of wood and it&apos;s not exactly right.  That makes you think more, so you can take off from that.

Quand j&apos;écris du code et que ce n&apos;est pas exactement comme je voudrais, ça me force à réfléchir. Donc écrire du code temporaire, qui n&apos;est pas parfait, est une action qui apporte des idées et qui provoque des réflexions : ce n&apos;est pas du temps perdu.

&gt; You&apos;re now acting and reacting. So it&apos;s kind of an experiment to get it all to feel correct.

Quand j&apos;écris du code j&apos;essaie d&apos;arriver le plus rapidement possible à cet état d&apos;action / réaction. J&apos;ai besoin de feedback rapide pendant que je travaille. Ce sont ces actions / réactions qui me conduisent à du code correct. Il ne s&apos;agit pas de beaucoup réfléchir pour avoir l&apos;idée parfaite, pour ensuite agir de façon parfaite, mais bien d&apos;alterner action / réflexion.

&gt; You have to do a lot of experimenting to get that just right.

Idem quand j&apos;écris du code. Comme disait un de mes professeurs de musique : c&apos;est l&apos;action qui apporte l&apos;idée, pas l&apos;inverse.

&gt; But I&apos;m always trying to gather what I call &quot;fire wood&quot;. So I have piles of things I can go to and see if they&apos;ll work.

Dans mon métier aussi j&apos;essaie de récupérer des idées et des pratiques un peu largement, explorer de nouvelles façons de faire, garder un esprit ouvert pour préparer la suite. J&apos;ai l&apos;impression aussi de récolter du bois pour le feu que je pourrai mobiliser quand j&apos;en aurai besoin.

Les citations avec un peu plus de contexte si vous voulez en savoir plus :

&gt; To me, every film, every project, is an experiment. How do you translate this idea? How do you translate it so that it goes from an idea to a film or to a chair? You&apos;ve got this idea, and you can see it and hear it and feel it and know it. Now, let&apos;s say you start cutting a piece of wood and it&apos;s not exactly right. That makes you think more, so you can take off from that.  You&apos;re now acting and reacting. So it&apos;s kind of an experiment to get it all to feel correct.
&gt;
&gt; — Catching the Big Fish, p. 29

&gt; Sound is so important to the feel of a film. To get the right presence for a room, the right feel from the outside, or the right sounding dialogue is like playing a musical instrument. You have to do a lot of experimenting to get that just right. It usually happends after the film is cut. But I&apos;m always trying to gather what I call &quot;fire wood&quot;. So I have piles of things I can go to and see if they&apos;ll work. You just have to pop one sound in, and you realize rightaway, Oh, that is not working.
&gt;
&gt; — Catching the Big Fish, p. 67

Night Blooming Jasmine
            </description>
            <pubDate>2025-07-24</pubDate>
            <guid>gemini://sroccaserra.fr/billets/2025-07-24_meteo.gmi</guid>
        </item>
        <item>
            <title>Techniques de mémorisation</title>
            <link>gemini://sroccaserra.fr/articles/2025-03-06_techniques_de_memorisation.gmi</link>
            <description>Parmi mes nombreuses lubies, il m&apos;est arrivé de m&apos;intéresser à la magie, et ce faisant j&apos;ai découvert quelques techniques de mémorisation que j&apos;utilise régulièrement dans ma vie quotidienne. Voici quelques réflexions sur le sujet, et quelques techniques simples et utiles.

## La mémoire est un muscle

Harry Lorayne, qui était magicien et spécialiste de la mémoire, disait que le vrai problème n&apos;est pas qu&apos;on oublie une chose, le problème est qu&apos;en réalité on ne l&apos;a pas réellement mémorisée.

En effet, mémoriser est un effort, et mémoriser durablement une information demande de se plier à cet effort.

La première technique pour mieux mémoriser est donc... d&apos;accepter de prendre le temps de mémoriser. Et si on a pas l&apos;habitude, au début il faudra accepter d&apos;y passer un peu plus de temps.

La bonne nouvelle, c&apos;est que la mémoire est un muscle, et qu&apos;avec l&apos;habitude, le temps de mémorisation peut se raccourcir.

## Pour mémoriser il faut se rappeler

Ce qui crée la mémorisation d&apos;une information à moyen et long terme, c&apos;est l&apos;effort d&apos;essayer de s&apos;en rappeler. Quelle que soit la méthode utilisée, pour mémoriser une information il faut donc l&apos;apprendre, mais surtout, aller chercher à nouveau cette information dans notre mémoire.

Et d&apos;aller la chercher plusieurs fois. Les champions de mémorisation de jeux de cartes entiers utilisent des techniques qui font qu&apos;ils ont au moins cinq fois l&apos;occasion de se rappeler de chaque carte.

Dans l&apos;idéal il faut étaler ces rappels dans le temps. Par exemple, essayer de mobiliser l&apos;information apprise le jour même, puis le lendemain, puis quelques jours après, puis une semaine après, (voire un mois après si on a le temps de le faire et qu&apos;on veut mémoriser à très long terme). C&apos;est pour ça qu&apos;il vaut mieux commencer à apprendre un cours à l&apos;avance, afin d&apos;avoir le temps de consolider l&apos;apprentissage dans le temps.

## Mémoriser par répétition

C&apos;est la technique qu&apos;on utilise en général, on lit et relit jusqu&apos;à ce que ça rentre. Cette technique a l&apos;avantage qu&apos;on peut l&apos;utiliser tout de suite : tout le monde sait lire et relire un texte. Et en effet, une forme de répétition est souvent nécessaire.

On peut quand même l&apos;améliorer un peut. Ce que j&apos;utilise, pour mémoriser un poème par exemple :

* Lire attentivement le premier vers.
* Cacher le texte ou fermer les yeux, et réciter le premier vers.
* Lire attentivement le premier vers et le deuxième vers (ne pas sauter le premier vers pour gagner du temps).
* Cacher le texte ou fermer les yeux, et réciter les deux vers.
* Et ainsi de suite jusqu&apos;à avoir lu et récité le poème entier.

L&apos;avantage est de mémoriser très progressivement, par petits morceaux, et d&apos;avoir besoin de se souvenir de chaque vers plusieurs fois.

Note : si le poème est très long, ça peut prendre beaucoup de temps. En effet, on va lire puis réciter 1+2+3+4+... vers, la somme augmente très vite avec le nombre total de vers. On peut donc travailler strophe par strophe si nécessaire.

Le lendemain, ou les fois suivantes, on peut concentrer nos efforts sur les parties qu&apos;on a eu du mal à réciter : ajouter une intention aux répétitions.

La même technique peut fonctionner pour une définition, ou un texte. Chaque phrase est comme un vers, et chaque paragraphe est une strophe. Ou sur une liste de dates à apprendre par exemple.

Pour mémoriser un chapitre d&apos;histoire, on n&apos;aura pas envie d&apos;apprendre tout le texte par cœur, ça prendrait trop de temps. On peut cependant utiliser cette technique pour mémoriser le plan du chapitre par cœur, et ensuite mémoriser un peu moins fidèlement le contenu.

## Mémoriser par associations

La méthode précédente fonctionne bien pour commencer, et peut même suffire. Cependant on mémorise mieux des associations, donc une bonne technique pour mémoriser une liste d&apos;informations est d&apos;associer chaque information à quelque chose.

Ces techniques demandent cependant un investissement préalable.

### Association à une liste fixe

Par exemple, voilà une technique que j&apos;utilise pour mémoriser une liste de courses, et qui peut très bien fonctionner pour mémoriser un plan de document par exemple. J&apos;ai au préalable mémorisé une liste fixe de dix choses, toujours les mêmes. Ma liste est celle-ci, et je l&apos;ai choisi parce-que les sonorités ressemblent (de loin) aux nombres qui y sont associés.

* Main (un)
* Feu (deux)
* Roi (trois)
* Âtre (quatre)
* Singe (cinq)
* Scie (six)
* ...

Ensuite, si je dois me souvenir d&apos;une liste de courses avec des pommes de terre, du chocolat, du dentifrice, des yaourts et des cartouches d&apos;encre par exemple, je vais faire l&apos;effort de créer mes associations. C&apos;est cet effort qui me permet de mémoriser. Je vais prendre le temps d&apos;imaginer :

* Une main qui tient plusieurs pommes de terres
* Du chocolat en feu, qui fond et qui dégouline
* Un roi qui se lave les dents avec du dentifrice sur la bouche
* Des yaourts posés dans l&apos;âtre d&apos;une cheminée
* Un singe tout taché d&apos;encre bleue

On se souvient mieux des associations incongrues, donc si ces images sont un peu loufoques c&apos;est tant mieux.

Certaines personnes se fabriquent des listes de plus de dix, mais personnellement je ne vais pas au delà.

### Méthode des loci

Une variante est la méthode des loci. Locus veux dire lieu en latin, et loci est le pluriel de locus. C&apos;est la technique du &quot;palais mental&quot; si on veut faire le malin comme Sherlock Holmes dans la série Sherlock (quel poseur).

L&apos;effort préalable est de visualiser un lieux familier, comme une maison d&apos;enfance, et d&apos;y identifier des emplacements précis. On associe ensuite chaque information qu&apos;on veut mémoriser à un emplacement.

On peut aussi visualiser un chemin qu&apos;on parcourt régulièrement, comme le trajet pour aller au travail, ou le trajet pour aller à la piscine si on préfère. L&apos;essentiel est de pouvoir parcourir vos emplacement précis dans ces lieux pour faire vos associations et ensuite les retrouver facilement.

Je n&apos;utilise pas cette méthode, mais elle est connue et populaire.

### Le code chiffres-sons

J&apos;aime beaucoup cette méthode pour mémoriser des nombres, et je m&apos;en sers plus souvent que je ne l&apos;aurais imaginé. Je m&apos;en sers à chaque fois que je dois taper mon code de carte bleue, de carte tickets restaurants, ou les divers codes pin que la vie met sur mon chemin.

L&apos;idée est d&apos;associer un son consonant aux 10 chiffres de base, de zéro à neuf. J&apos;utilise la même correspondance que sur la page Wikipédia, que vous trouverez dans les liens en fin d&apos;article.

Ensuite, pour mémoriser une suite de nombres, comme un code pin, je trouve des mots qui ont les bonnes consonnes et je crée des associations intéressantes. La correspondance chiffres-sons est uniquement phonétique, donc on a de la souplesse sur l&apos;orthographe des mots.

Par exemple, il y a des années j&apos;ai parlé de cette méthode lors d&apos;un repas avec des collègues. Ils m&apos;ont donné un nombre à mémoriser, et je me souviens encore des mots que j&apos;ai choisi : &quot;tomme de chèvre&quot;. Donc je me souviens encore du nombre : 131684.

Cette technique marche très bien pour les dates. Si vous voulez vous souvenir de la date de naissance de François Villon, 1431, vous pouvez imaginer une &quot;dure amande&quot;, et qu&apos;il se fait mal aux dents en la croquant et vous aurez cette date en tête pour un moment. Et peut-être que vous penserez aux neiges d&apos;antan la prochaine fois que vous croquerez une amande.

### L&apos;effort ne disparaît pas

On le voit, ces méthodes par associations ne dispensent pas de l&apos;effort, elles le rendent explicite et un peu moins barbant (un peu).

Avec l&apos;habitude, elles accélèrent aussi le processus de mémorisation, car une fois que vous connaissez bien votre liste d&apos;association, et que vous avez pris l&apos;habitude de mémoriser des informations, ça va un peu plus vite. Et je trouve que je me souviens beaucoup plus longtemps des choses que j&apos;ai mémorisées avec ces techniques.

## Conclusion

Je trouve que ces techniques peuvent être utiles dans beaucoup de contextes, et je m&apos;étonne même que certaines d&apos;entre elles ne soient pas systématiquement enseignées aux enfants : quand on est en phase d&apos;apprentissage, on a très souvent besoin de mémoriser beaucoup de choses, et apprendre ces techniques dès l&apos;enfance permettrait d&apos;en bénéficier plus tôt.  D&apos;autant que ces techniques ne sont pas nouvelles, certaines remontent à l&apos;antiquité.

## Liens

=&gt; https://en.wikipedia.org/wiki/Harry_Lorayne
=&gt; https://fr.wikipedia.org/wiki/M%C3%A9thode_des_loci
=&gt; https://fr.wikipedia.org/wiki/Code_chiffres-sons
            </description>
            <pubDate>2025-03-06</pubDate>
            <guid>gemini://sroccaserra.fr/articles/2025-03-06_techniques_de_memorisation.gmi</guid>
        </item>
        <item>
            <title>(Abstraction + Encapsulation) ❤️ (Aligner Tech + Métier)</title>
            <link>gemini://sroccaserra.fr/articles/2025-01-07_abstraction_encapsulation_et_metier.gmi</link>
            <description>Dans une discussion récente, un collègue s&apos;interrogeait sur sa vision du code, et se demandait quel était le &quot;bon curseur&quot; sur l&apos;abstraction à utiliser par des développeurs·euses pour à la fois exprimer le métier du produit, et conserver une maîtrise sur la complexité du code.

J&apos;ai trouvé sa question intéressante, et j&apos;ai noté ci-dessous ce qu&apos;elle m&apos;a évoqué.

Tout d&apos;abord, je n&apos;ai pas de réponse absolue à ce que serait le bon curseur. J&apos;aurais envie de conseiller de commencer par chercher des références sur les concepts d&apos;abstraction et d&apos;encapsulation. Ensuite de reconnaître dans nos pratique ce qui y ressemble, et de pratiquer en équipe ce qu&apos;on a appris ensemble.

## Définitions

Mais pour préciser un peu, qu&apos;est-ce que j&apos;appelle abstraction et encapsulation ? Ces concepts ont été popularisés par la programmation orientée objet, et pour moi ils en sont le cœur. Cependant ces concepts sont indépendants de ce paradigme, et je peux les utiliser dans mes réflexions, quel que soit le paradigme utilisé.

Voilà comment Grady Booch (et al.) les définissait dans son livre Object-Oriented Analysis and Design :

&gt; Abstraction focuses on the essential characteristics of some object, relative to the perspective of the viewer.

&gt; Encapsulation hides the details of the implementation of an object.

Ce sont des notions proches et qui vont ensemble. L&apos;abstraction permet de prendre le point de vue de l&apos;observateur·rice et de se concentrer sur les caractéristiques essentielles. Elle permet parfois aussi de généraliser un comportement, comme les classiques Abstract Data Types. Si je prends l&apos;exemple d&apos;une pile : quels que soient les objets qu&apos;elle contient, une pile permet d&apos;empiler (push) et de dépiler (pop). Push et pop sont les caractéristiques essentielles qui la définissent.

L&apos;encapsulation cache les détails d&apos;implémentation, c&apos;est à dire qu&apos;en tant qu&apos;utilisateur d&apos;une pile, on ne doit pas savoir comment elle est implémentée. Ça peut être un tableau, ou une liste chaîné, ce détail ne doit pas changer son usage où que ce soit dans le code. À part dans le code de son implémentation.

=&gt; https://en.wikipedia.org/wiki/Stack_(abstract_data_type) Stack (abstract data type)

## Perspective

J&apos;ai utilisé l&apos;exemple de la pile pour illustrer, mais ces concepts vont plus loin, et en tirent d&apos;autres. Ils rejoignent souvent l&apos;architecture et le design de code. Voilà trois exemples de plus haut niveau, dont on n&apos;a à mon avis pas encore tiré tous les bénéfices :

* La notion de couches, un peu comme le modèle OSI mais au niveau du code.
* La notion d&apos;injection de dépendances, qui permet de rendre le code testable et modifiable quand on a des dépendances volatiles.
* Plus finement, la question qu&apos;on peut se poser ensemble dès qu&apos;on regarde un bout de code : &quot;est-ce que ces 5 lignes de code manipulent des éléments qui sont au même niveau d&apos;abstraction ?&quot;

En passant, ces notions sont parfois utilisées par la communauté DDD, mais elles ont de la valeur en soi, même si on ne fait pas de DDD.

La notion de couche permet d&apos;organiser le code par niveaux d&apos;abstraction. Elle nous invite à réfléchir ensemble à comment on veut structurer et concrétiser nos couches. Les notions de module et d&apos;API (au sens large de Programming Interface, d&apos;un module ou autre) peuvent nous aider à les rendre concrètes.

Par exemple on peut imaginer d&apos;avoir une couche métier, dans laquelle on ne va avoir que des notions métier. Quand on lit et écrit du code dans cette couche, on ne réfléchit qu&apos;au métier, sans mélanger les problèmes de formats de fichiers, et sans avoir à se souvenir comment fonctionne notre ORM ni comment écrire un Group By. Les considérations techniques ne nous encombrent pas. Cet exemple est le pattern Domain Model. Je paraphrase Romeu Moura : même si on était capable de réfléchir à tout en même temps, pourquoi est-ce qu&apos;on s&apos;infligerait ça ?

Note : comme tout pattern, le pattern Domain Model a ses contextes où il est utile, et ses contextes où il apporte plus de complexité que d&apos;utilité. C&apos;est la même chose pour la notion de couches, à vous de voir si une organisation en couches est pertinente dans votre cas.

La notion d&apos;injection de dépendances permet de rendre explicites les relations entre couches par exemple, voire même de les inverser (avec un petit formalisme supplémentaire). Si je fais un plat de spaghettis où tout dépend de tout, mes injections de dépendances vont me le montrer. En plus de ça, injecter les dépendances permet de faciliter l&apos;écriture de tests automatiques.

Et la question &quot;est-ce que ces 5 lignes de code manipulent des éléments qui sont au même niveau d&apos;abstraction ?&quot; peut souvent mener à démêler les plats de spaghettis justement, voire à éviter de les créer.

Quand je dis qu&apos;on n&apos;a pas encore tiré tous les bénéfices de ces trois points, je veux dire que dans les projets que j&apos;observe et auxquels je participe, ces trois points sont à améliorer en permanence. Ils font l&apos;objet d&apos;un équilibre instable, et nous demandent un effort pour les maintenir. Il y a des idées et des outils qui aident, comme :

* La revue de code
* Les tests automatisés
* Le refactoring
* L&apos;architecture hexagonale

Mais en conserver la cohérence demande de la maintenance au quotidien, et de la communication dans l&apos;équipe.

## Abstraction et encapsulation : pas automatique

Je disais plus haut que j&apos;essaie d&apos;introduire de la complexité quand son coût est inférieur aux bénéfices qu&apos;on en retire : j&apos;aime aussi rester pragmatique.

Pour donner un exemple caricatural je peux écrire un script shell que je n&apos;utiliserai qu&apos;une fois sans aucune abstraction, avec des for et des if imbriqués, tant que je peux vérifier facilement et tout au long de l&apos;écriture qu&apos;il fonctionne comme je l&apos;imagine.

J&apos;ajoute ici nouvelle idée, dont à mon avis on n&apos;a pas encore tiré tous les bénéfices. Quand j&apos;écris du code, même quand je n&apos;utilise ni abstraction, ni encapsulation, ni aucun pattern précis, je me demande toujours comment est-ce que je vais pouvoir :

* Vérifier qu&apos;il marche au fil de l&apos;écriture et pas à la fin ?
* Le modifier quelques temps plus tard en m&apos;assurant que je n&apos;ai rien cassé ?

Dans le cas précédent, le script shell à usage unique, ça peut être une série de printf qui vont valider mes hypothèses au fil de l&apos;eau. Ou pourquoi pas, des tests automatisés quand les vérifications commencent à être nombreuses. Je remarque aussi que très vite, ces vérifications vont m&apos;inciter à introduire au moins de l&apos;encapsulation, pour pouvoir faire des vérifications indépendantes des implémentations.


## Maintenance et Alignement Métier

Et pour revenir au titre, je me dis aussi que ces activités de maintenance et d&apos;équilibre, nos choix d&apos;abstraction et l&apos;organisation de notre code, ont d&apos;autant plus de sens si on les mène dans la perspective d&apos;aligner la technique et le métier. Il ne s&apos;agit surtout pas de faire une abstraction ou une encapsulation techniquement parfaite, mais qui rendrait l&apos;expression du besoin métier plus complexe que nécessaire. Sinon on n&apos;en retirera pas les bénéfice, voire on le paiera. Sandy Metz en donne des exemples dans ses réflexions et conférences sur la &quot;Wrong Abstraction&quot;, par exemple :

&gt; Prefer duplication over the wrong abstraction.

=&gt; https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction The Wrong Abstraction

Et que si on développe à plusieurs (i.e. dans mon cas, tout le temps), c&apos;est important que ces activités soient l&apos;occasion de discussions qui créent de l&apos;alignement entre nous, sur la tech et le métier, sinon on passe également à côté du sujet.

Là encore, la communauté DDD s&apos;intéresse beaucoup à aligner le code avec le métier. Et dans son livre Domain-Driven Design, Eric Evans utilise beaucoup le mot &quot;abstraction&quot;, pour en effet prendre le point de vue du métier, et en exprimer l&apos;essentiel (il parle même de distiller à un moment). Pour ne citer que les deux premières occurrences du mot :

&gt; A domain model [...] is not just the knowledge in a domain expert’s head; it is a rigorously organized and selective abstraction of that knowledge.

Et :

&gt; The abstractions are true business principles.

## Conclusion

J&apos;ai été content de réfléchir à ces sujets, et de regrouper :

* Une définition de l&apos;abstraction et de l&apos;encapsulation.
* Des patterns de design de plus haut niveau.
* Un rappel rapide de se poser la question si ces patterns sont pertinents dans votre contexte.
* Les questions de vérification que le code fonctionne.
* La notion de maintenance.
* L&apos;alignement de la tech et du métier.

Et je me rends compte que j&apos;ai évoqué là, en accéléré, une grande partie de ce à quoi je réfléchis à chaque fois que je travaille avec du code. Et vous, à quoi est-ce que vous réfléchissez quand vous travaillez avec du code ?

## Bonus

### La notion de frontière

Quand je vois que de l&apos;encapsulation va être bénéfique, j&apos;utilise beaucoup la notion de frontière. Par ordre croissant :

* Un bloc de scope est une frontière
* Une fonction est une frontière
* Une interface est une frontière
* Un module est une frontière
* Une couche est une frontière
* Une API est une frontière

### Deux exemples d&apos;encapsulation hors programmation objet

Si vous avez lu jusque là, et que vous voulez en savoir plus, voilà deux exemple d&apos;abstraction et d&apos;encapsulation hors du paradigme de programmation objet.

Cet article montre comment faire des types de données abstraits et même de l&apos;encapsulation en programmation fonctionnelle (ici Haskell) :

=&gt; https://wiki.haskell.org/Abstract_data_type Abstract Data Type (HaskellWiki)

Et en programmation structurée, en C par exemple : on peut masquer les détails d&apos;implémentation en ne mettant que les déclarations dans les fichiers .h, et en cantonnant les implémentations dans les fichiers .c. On peut même cacher les détails de la représentation des données en ne déclarant que des pointeurs vers des structures dans les fichier .h, par exemple :

```c
// in dictionnary.h:
typedef struct dictionnary *Dictionnary;
```
            </description>
            <pubDate>2025-01-28</pubDate>
            <guid>gemini://sroccaserra.fr/articles/2025-01-07_abstraction_encapsulation_et_metier.gmi</guid>
        </item>
        <item>
            <title>Modéliser avec du code</title>
            <link>gemini://sroccaserra.fr/articles/2024-11-05_modeliser_avec_du_code.gmi</link>
            <description>Cet après-midi, je relisais le chapitre 8 du livre Domain-Driven Design, et j&apos;ai été très intéressé par ce qui y est dit en introduction, sur la modélisation métier avec du code.

Notamment cet extrait, que je cite tel quel. Vous pouvez vous arrêter à l&apos;extrait, et je me garderais bien de penser que je pourrais y ajouter quelque chose, mais si ça vous intéresse je me permettrai de partager pourquoi je trouve cet extrait intéressant, et mes réflexions sur quelques points plus bas.

&gt; The traditional way of explaining object analysis involves identifying nouns and verbs in the requirements documents and using them as the initial objects and methods. This explanation is recognized as an oversimplification that can be useful for teaching object modeling to beginners. The truth is, though, that initial models usually are naive and superficial, based on shallow knowledge.
&gt;
&gt; For example, I once worked on a shipping application for which my initial idea of an object model involved ships and containers. Ships moved from place to place. Containers were associated and disassociated through load and unload operations. That is an accurate description of some physical shipping activities. It does not turn out to be a very useful model for shipping business software.
&gt;
&gt; Eventually, after months working with shipping experts through many iterations, we evolved a quite different model. It was less obvious to a layperson, but much more relevant to the experts. It was refocused on the business of delivering cargo.
&gt;
&gt; The ships were still there, but abstracted in the form of a “vessel voyage,” a particular trip scheduled for a ship, train, or other carrier. The ship itself was secondary, and could be substituted at the last minute for maintenance or a slipping schedule, while the vessel voyage went on as planned. The shipping container all but disappeared from the model. It did emerge in a cargo-handling application in a different, very complex form, but in the context of the original application, the container was an operational detail. The physical movement of the cargo took a back seat to the transfers of legal responsibility for that cargo. Less obvious objects, such as the ”bill of lading,” came to the fore.
&gt;
&gt; Whenever new object modelers showed up on the project, what was their first suggestion? The missing classes: ship and container. They were smart people. They just hadn’t gone through the process of discovery.
&gt;
&gt; ―Domain-Dreven Design, Deep Models, p. 189-190

Je trouve cet extrait particulièrement intéressant, car il résonne beaucoup avec ce que j&apos;observe quand j&apos;essaie de modéliser du métier avec du code, afin de résoudre un problème concret. Il donne aussi un exemple en peu de mots qui permet de toucher du doigt en quoi c&apos;est difficile de bien saisir les termes métier qui sont importants pour la modélisation.

Voilà quelques points qui m&apos;ont marqué et pourquoi.

## Modélisation objet, mais aussi fonctionnelle

Le premier point est qu&apos;il parle de modélisation objet, qui était le paradigme dominant à la sortie du livre. Mais à mon avis, ce qu&apos;il dit s&apos;applique également à une modélisation fonctionnelle, autour de types et de fonctions sur ces types par exemple.

## La compréhension du modèle évolue

&gt; The truth is, though, that initial models usually are naive and superficial, based on shallow knowledge.

Ça correspond à ce que j&apos;ai observé, et si c&apos;est vrai ça explique pourquoi il est si difficile de trouver le bon modèle tout de suite en début de projet. Et donc nécessairement, tout au long du projet on trouvera de meilleures modélisations, et quand c&apos;est possible il serai important de retravailler le code pour qu&apos;il s&apos;adapte à ces meilleures modélisations.

On peut aussi en déduire l&apos;importance de choisir une conception  et des patterns de code qui rendent les changements faciles, ou plus réalistement, moins difficiles.

## Un exemple de modélisation intuitive... mais peu utile

&gt; For example, I once worked on a shipping application for which my initial idea of an object model involved ships and containers.

L&apos;exemple de première modélisation intuitive qu&apos;il donne dans l&apos;extrait me parle beaucoup : comment en effet ne pas penser que les notions de Ship et de Container seront centrales dans une application qui gère des transports maritimes ?

Mais la conclusion interroge :

&gt; It does not turn out to be a very useful model for shipping business software.

## Trouver une modélisation réellement utile pour le problème

&gt; Eventually, after months working with shipping experts through many iterations, we evolved a quite different model. [...] It was refocused on the business of delivering cargo.

Je note qu&apos;il leur a fallu plusieurs mois de travail avec des experts pour arriver à la modélisation qui convenait au problème. C&apos;est une des raisons pour lesquelles développer un logiciel prend du temps : ce n&apos;est pas le temps d&apos;écrire le code, c&apos;est le temps nécessaire à comprendre le problème de la bonne façon.

&gt; The ships were still there, but abstracted in the form of a “vessel voyage,” a particular trip scheduled for a ship, train, or other carrier. The ship itself was secondary, and could be substituted at the last minute for maintenance or a slipping schedule, while the vessel voyage went on as planned.

L&apos;auteur donne là un exemple intéressant de la nouvelle modélisation avec la notion de voyage de navire, et un cas d&apos;usage qui montre pourquoi cette modélisation est meilleure.

## Certaines notions sont inutiles dans certains contextes...

Et ensuite il nous indique qu&apos;une des notions qu&apos;on aurait envie d&apos;avoir intuitivement, la notion de Container, s&apos;est révélée inutile dans le contexte de cette application :)

&gt; The shipping container all but disappeared from the model. [It] was an operational detail.

&gt; It did emerge in a cargo-handling application in a different, very complex form.

Mais que cette notion s&apos;est avérée utile dans le contexte d&apos;une autre application : si on essaie d&apos;avoir une modélisation unique pour toutes nos applications, on risque de surcharger nos modèles, et de faire peser sur toutes nos applications les contraintes de toutes les autres.

## ... D&apos;autres sont utiles et ne sont pas évidentes a priori

&gt; The physical movement of the cargo took a back seat to the transfers of legal responsibility for that cargo. Less obvious objects, such as the ”bill of lading,” came to the fore.

Les notions les plus utiles pour résoudre le problèmes ne sont pas toujours évidentes à trouver, et il sera nécessaire de passer du temps sur le problème et de faire de la place dans notre modèle, en évitant de tout modéliser au profit de ce va dans le sens du bois.

## Une modélisation utile est un chemin

&gt; Whenever new object modelers showed up on the project, what was their first suggestion? The missing classes: ship and container. They were smart people. They just hadn’t gone through the process of discovery.

Pour finir et pour conclure, je note deux points ici que j&apos;ai également observés :

* Chaque nouvelle personne dans l&apos;équipe aura besoin de suivre le chemin qu&apos;a suivi la modélisation pour se l&apos;approprier
* On sera alors amenés à avoir des conversations au sein de l&apos;équipe pour accompagner ces personnes sur le chemin

Et enfin, je me sens obligé de préciser a posteriori qu&apos;il n&apos;est pas question de complexifier inutilement une modélisation évidente qui répondrait très bien au problème. Ça existe également. Et quand c&apos;est le cas, on peut se réjouir d&apos;utiliser une modélisation évidente qui va dans le sens du bois.

## Références

=&gt; https://www.informit.com/store/domain-driven-design-tackling-complexity-in-the-heart-9780321125217 Domain-Driven Design (Livre)
            </description>
            <pubDate>2024-11-05</pubDate>
            <guid>gemini://sroccaserra.fr/articles/2024-11-05_modeliser_avec_du_code.gmi</guid>
        </item>
        <item>
            <title>Imiter vs. Éprouver</title>
            <link>gemini://sroccaserra.fr/articles/2024-10-22_imiter_vs_eprouver.gmi</link>
            <description>Ce matin j&apos;ai lu un article qui montre une façon dont le livre Accelerate peut être mal compris / utilisé. Sa lecture a été l&apos;occasion pour moi de rassembler plusieurs sujets qui me paraissent intéressants en ce moment. Extrait :

&gt; The problem is that managers, upon reading the book, see it not as interesting research that can spur their own experiments, but as a prescription to producing a &apos;High Performing Technology Organisation&apos;, despite the authors proclamation on pages 136-140 that correlation does not equal causation, and that they didn&apos;t do any causal analysis, because &quot;we did not have the data necessary for this kind of work&quot; (bottom of page 139).

=&gt; https://gist.github.com/sleepyfox/347575d736e1d52d5dcf104cb8ca9169 Time to decelerate

## Imiter sans éprouver

Tout d&apos;abord, je pense que cette façon de passer à côté de l&apos;essentiel n&apos;est pas réservée aux managers. Et je pense aussi qu&apos;elle s&apos;applique à d&apos;autres sujets, comme l&apos;amélioration continue par exemple.

Ensuite, pour résumer ce que j&apos;ai en tête à ce sujet, et que j&apos;observe régulièrement depuis que j&apos;y fais attention : dans une équipe donnée, si on se contente d&apos;*imiter* ce que fait une autre équipe, sans l&apos;*éprouver*, on n&apos;en retire que peu de bénéfice.

&gt; imiter [imite] v. tr.
&gt;
&gt; [1] s&apos;efforcer de faire la même chose que (qqn), chercher à reproduire (les attitudes, les gestes d&apos;une personne, d&apos;un animal, des voix, des sons, des bruits…).
&gt; ➙ Contrefaire, copier, mimer, répéter, reproduire, simuler.
&gt;
&gt; — Le Robert

&gt; éprouver [epʀuve] v. tr.
&gt;
&gt; [1] essayer (qqch.) pour vérifier quelle est la valeur, la qualité.
&gt; ➙ Expérimenter.
&gt; ➙ Essayer, tâter (de) ; pratique (mettre en).
&gt;
&gt; [3] apprécier, connaître par une expérience personnelle ; se rendre compte de.
&gt; ➙ Constater, réaliser, reconnaître.
&gt;
&gt; — Le Robert

## L&apos;importance d&apos;éprouver

Ça souligne pour moi l&apos;importance de ne pas se contenter d&apos;imiter des pratiques, mais de les éprouver. Donc d&apos;expérimenter, et tout aussi important, de vérifier régulièrement ce que l&apos;expérimentation nous apporte. Où en est-on suite à cette expérimentation ? Est-ce qu&apos;elle nous emmène vers ce qu&apos;on veut atteindre ? Est-ce qu&apos;elle nous emmène ailleurs ? Est-ce que cette nouvelle destination est préférable à la cible initiale ?

Deux formules me viennent en tête, qui incluent ces questions. Dans &quot;Inspect &amp; Adapt&quot;, il y a &quot;Inspect&quot;. Dans &quot;Plan, Do, Check, Act&quot;, il y a &quot;Check&quot;. Il se trouve que ces formules sont souvent citées dans des contextes agiles, mais ces questions sont utiles quand on parle d&apos;amélioration continue en général.

Je pense aussi à cette citation de J. B. Rainsberger, qui nous invite à mettre à jour le plan quand on acquière une meilleure compréhension de notre position :

&gt; When reality stops matching the plan, change the plan (instead of pushing the plan harder).

Il existe des outils pour se poser ces questions sur nos expérimentations. Par exemple :

* Les rétrospectives
* Les timeboxs avec débriefs
* Le feedback rapide

Et tout ce qui facilite la communication peut aider.

## Digression sur le mot &quot;éprouver&quot;

J&apos;avais depuis longtemps des réflexions sur la notion d&apos;imitation, mais confronter cette notion à la notion d&apos;éprouver est récent pour moi.

Je suis arrivé à &quot;épreuve&quot; puis à &quot;éprouver&quot; cette semaine, en visionnant une conférence de Bruno Latour.

Dans cette conférence, plutôt que de se contenter d&apos;utiliser des termes sans les remettre en question (sans les éprouver), ce qui revient à :

&gt; enfiler des séries de clichés les uns derrière les autres qui n’ont aucune espèce de signification

Il nous invite à :

&gt; transformer ces termes en les ramenant à leur monde d’attributs, de propriétés ou de performances

Il donne deux façons de questionner notre contexte par des épreuves.

La première est quand on n&apos;a pas d&apos;information sur ce qu&apos;on observe. On va donc conduire des expériences, des épreuves, pour en déterminer des attributs, et ainsi découvrir des compétences de notre contexte en l&apos;éprouvant.

La deuxième, c&apos;est quand on pense connaître ce qu&apos;on observe. On peut alors en déduire des attributs, qu&apos;on va vérifier par des épreuves. Si les épreuves révèlent que ce qu&apos;on observe n&apos;a pas les attributs prévus, c&apos;est un signe qu&apos;on n&apos;est pas en train d&apos;observer exactement ce qu&apos;on pensait observer, ou qu&apos;on le connais moins bien que ce qu&apos;on imaginait.

Dans les deux cas, on va éprouver, faire subir des épreuves à notre sujet pour le connaître ou vérifier qu&apos;il a bien les attributs qu&apos;on imagine.

## It ain’t what we don’t know that gets us in trouble, it’s what we know that ain’t so

Dans mon expérience je suis très souvent surpris de ce que je découvre en faisant ça, et quand je n&apos;éprouve pas un minimum mon sujet, je me crée des problèmes à cause de ce que je croyais savoir, mais qui était faux.

Ça a l&apos;air un peu trivial, mais ça me parle beaucoup, car dans des contextes missions je pense souvent aux inconnues connues, voire aux inconnues inconnues, mais parfois ce n&apos;est pas ça qui coince. J&apos;observe régulièrement que je me créé des problèmes à cause d&apos;une hypothèse que j&apos;avais faite sur mon contexte mission, que je n&apos;ai pas vérifiée, et que j&apos;aurais pu valider / invalider facilement en l&apos;éprouvant. 

Dans Secrets of Consulting, de Jerry Weinberg, on trouve cette citation :

&gt; It ain’t what we don’t know that gets us in trouble, it’s what we know that ain’t so.

## Conclusion

Après ce long tour, où j&apos;ai pris le risque de mettre ensemble des choses différentes, en m&apos;autorisant à me tromper, j&apos;en reviens à Imiter vs. Éprouver.

Pour moi, pour tirer plus de bénéfices d&apos;Accelerate, ce n&apos;est pas (seulement) l&apos;imitation de ce que font d&apos;autres équipes qui crée de la compétence, c&apos;est ce qu&apos;on apprend collectivement sur notre contexte d&apos;équipe, d&apos;entreprise, etc. en l&apos;éprouvant.

J&apos;ai envie aussi de préciser que l&apos;imitation n&apos;est pas mauvaise en soit, imiter est aussi une façon d&apos;apprendre. Rien ne nous empêche d&apos;imiter ET d&apos;éprouver.
            </description>
            <pubDate>2024-10-22</pubDate>
            <guid>gemini://sroccaserra.fr/articles/2024-10-22_imiter_vs_eprouver.gmi</guid>
        </item>
        <item>
            <title>Quelques réflexions sur le métier de consultant</title>
            <link>gemini://sroccaserra.fr/articles/2024-06-26_quelques_reflexions_sur_le_metier_de_consultant.gmi</link>
            <description>Depuis que j&apos;ai rejoint OCTO Technology en 2015, quand je me présente professionnellement je dis que je suis &quot;consultant&quot;. Avant ça, j&apos;ai travaillé 15 ans chez des éditeurs de logiciels et je me présentais comme &quot;programmeur&quot;.

Ça va bientôt faire 10 ans que je dis &quot;consultant&quot;, et j&apos;ai envie de me demander ce que ça veut dire pour moi aujourd&apos;hui. Je propose de passer en revue quelques raisons. Il y en aurait sans doute beaucoup d&apos;autres, mais chercher à être exhaustif ne serait pas très intéressant.

## Ce que veux dire pour moi d&apos;être &quot;consultant&quot;

Quand je dis &quot;consultant&quot;, dans mon contexte ça veut dire &quot;consultant en informatique&quot;. C&apos;est un peu plus précis, mais &quot;informatique&quot;, ça reste vague.  Et pourquoi &quot;consultant&quot;, et pas &quot;prestataire&quot; par exemple ?

### Programmeur·ses ⊂ Prestataires ⊂ Consultant·es

Le premier point auquel je pense, c&apos;est que dans mon contexte, celui des missions de delivery logiciel, les prestataires sont aussi des programmeurs et programmeuses, et les consultant·es sont aussi des prestataires.  Je simplifie, car chez OCTO on a des consultant·es qui ne font pas ou peu de programmation.  Par exemple des Architectes, UX, Product Owner, Coach, ...

### Variété des missions

En tant que consultant ou prestataire, j&apos;ai l&apos;occasion de travailler sur plus de projets, car on est plus souvent amené·es à changer de mission et donc de projet qu&apos;une personne interne, qui restera souvent plus longtemps sur le même projet.

Et donc j&apos;ai l&apos;occasion de travailler dans plus d&apos;équipes, ça me permet d&apos;ouvrir mes horizons et de découvrir d&apos;autres façons de travailler.

Cette variété des missions fait qu&apos;en tant que prestataire ou consultant je peux apporter un regard neuf, différent de celui des personnes qui se seront habituées à certaines incohérences et qui ne les voient plus.

Je peux apporter des éléments nouveaux dans une équipe, ou parfois venir confirmer des choses déjà connues, les deux sont utiles.

Le revers de la médaille, c&apos;est que si on change de projet trop souvent, parfois on ne voit pas les conséquences à long terme des choix de l&apos;équipe.  Pour cette raison, je veille à faire régulièrement des missions longues, et à ne pas me contenter d&apos;enchaîner les missions de 6 mois. C&apos;est cet équilibre entre mission courtes et longues qui me convient.

### Les consultant·es sont consulté·es

Une autre facette de la variété des missions, qui va être un peu différent de la posture classique de prestataire, c&apos;est qu&apos;en tant que consultant on me consulte. En plus des missions de delivery, j&apos;ai régulièrement l&apos;occasion de faire des missions où on me demande mon avis sur quelque-chose. Par exemple des audits de code, des revues d&apos;architecture, des cadrages de missions. Je donne également des formations à des groupes.

C&apos;est alors d&apos;autant plus important pour moi d&apos;être capable d&apos;écouter (ne pas oublier cette partie !), d&apos;expliquer, de vérifier qu&apos;on se comprend le mieux possible, et de convaincre (ça en général on s&apos;en souvient bien).

Note : ça ne veut pas dire qu&apos;en tant que prestataire ou programmeur je ne donnerais pas mon avis et que je ne vais pas écouter ou convaincre, mais ça veut dire qu&apos;en tant que consultant on a plus souvent des missions où ça fait explicitement partie des attentes.

### On utilise beaucoup l&apos;intelligence collective

Ce n&apos;est pas forcément plus vrai que dans les autres postures, mais là encore, souvent ça fait explicitement partie de ma mission.

Et comme on arrive avec un regard externe, on prendra plus facilement la posture de facilitateur, avec plus de détachement.

## Quelques astuces de consultant·es

Voilà quelques astuces que j&apos;utilise souvent. On pourrait en lister beaucoup d&apos;autres, et ce n&apos;est en rien un résumé des activités du métier de consultant·e. Ce sont plutôt des choses que je vois revenir encore et encore dans la pratique de mon métier, et qui seront utiles pour toute activité où on travaille à plusieurs et où il est important de se comprendre.

### Commencer par expliciter l&apos;agenda

Quand on commence un travail à plusieurs en synchrone (réunion, atelier, ...), j&apos;apprécie beaucoup quand on commence par préciser l&apos;agenda, le déroulé à grosse maille, la liste d&apos;étapes qu&apos;on va suivre.

Ça permet aux personnes qui participent de se projeter, de savoir où en est de la réunion / de l&apos;atelier, et d&apos;anticiper un peu comment elles pourront participer ou ce qu&apos;elles pourront apprendre. Également, de vérifier qu&apos;elles sont au bon endroit et ne vont pas perdre leur temps.

### Communiquer les heures de début et de fin

En plus d&apos;avoir un agenda de réunion clair, quand j&apos;anime un travail collectif je précise le plus tôt possible la plage de temps qu&apos;on s&apos;accorde pour ce travail. Juste après l&apos;agenda par exemple, ou pourquoi pas avant.

J&apos;aime bien préciser également les horaires approximatifs des pauses si le travail dure plus d&apos;une heure trente.

Ça permet aux personnes qui participent de savoir :

* Qu&apos;on ne rentre pas dans un tunnel sans fin
* À quelle heure environ elles pourront passer un appel ou aller fumer par exemple
* Que leur organisation de déjeuner ou de fin de journée est compatible avec ce travail, et de s&apos;organiser tout de suite si ce n&apos;est pas le cas

Ça apporte tout de suite des réponses à des questions que beaucoup de personnes se posent, et ça permet de mieux se concentrer sur ledit travail.

### Rendre visible les conversations

C&apos;est dans une formation donnée par Alberto Brandolini que j&apos;ai compris l&apos;importance de ce point, et depuis je ne peux plus le dé-voir.

Parfois, quand on anime un travail collectif, on voit un groupe qui parle beaucoup et qui semble tourner en rond. Dans ce cas, je leur demande de rendre visible leur conversation, de la poser sur une table pour qu&apos;on puisse regarder la même chose ensemble.

Par exemple en écrivant sur des post-its ou un tableau blanc si on est en présentiel. À distance j&apos;utilise Miro, Excalidraw, ou un document texte collaboratif.

Quelques phrases que j&apos;utilise :

* J&apos;aime bien la façon dont tu viens de dire ça, est-ce que tu pourrais l&apos;écrire ?
* Comment est-ce qu&apos;on pourrait écrire ce qu&apos;on vient de dire ?

Le fait de rendre cette conversation visible permet aux personnes de vérifier qu&apos;elles se comprennent, de repérer les ambiguïtés, de choisir quoi creuser maintenant, et d&apos;arrêter de tourner en rond.

## Conclusion

Dans mon contexte, je suis à la fois consultant, prestataire, et programmeur.  Et j&apos;ai partagé quelques raison pour lesquelles ça a du sens pour moi de dire que je suis consultant aujourd&apos;hui. Il y a évidemment d&apos;autres raisons qu&apos;on pourrait lister, et beaucoup d&apos;autres définitions du job de consultant, probablement très différentes de ce que j&apos;ai proposé.

J&apos;espère également que les quelques astuces partagées en deuxième partie d&apos;articles seront utiles pour vos réunions et ateliers.

=&gt; https://mastodon.social/@sroccaserra/112683542919045194 🧵 @sroccaserra
            </description>
            <pubDate>2024-06-26</pubDate>
            <guid>gemini://sroccaserra.fr/articles/2024-06-26_quelques_reflexions_sur_le_metier_de_consultant.gmi</guid>
        </item>
        <item>
            <title>L'IA générative : pas encore une révolution ?</title>
            <link>gemini://sroccaserra.fr/articles/2024-06-10_ia_generative_-_pas_encore_une_revolution.gmi</link>
            <description>Quand je lis des articles ou que j’entends des interviews sur l’IA générative qui mettent en avant &quot;le potentiel&quot; de cette technologie, je ne suis pas convaincu. Pour moi c&apos;est un marqueur des technologies faiblement intéressantes.

Pour moi le signe des grandes avancées technologiques est qu&apos;elles s&apos;imposent, souvent assez rapidement, car elles ont déjà une utilité mesurable dans plusieurs secteurs variés, et c&apos;est leur utilité novatrice qui leur permet de s&apos;imposer. Je pense au cloud ou à la virtualisation par exemple, qui pour moi se sont imposés en partie parce-qu&apos;on en avait assez de courir derrière un vieux PC dans les locaux pour avoir un serveur de dev, et d&apos;attendre les validations de commandes de disques durs pour avoir un env de préprod. C&apos;était directement utile et on savait exactement pourquoi on s&apos;en servait.

Et le signe des &quot;hypes passagères&quot; est qu&apos;elles se présentent comme des choses avec un potentiel faramineux dans tous les secteurs, mais n&apos;ont pas encore d&apos;usage bien clair en dehors de quelques secteurs restreints. Je pense à la blockchain, aux NFT, au Metaverse, etc. Beaucoup d&apos;argent a changé de main mais ces technos se sont révélées comme une succession de miroirs aux alouettes qui prennent le relai l&apos;un de l&apos;autre.

Quand une avancée technologique n&apos;est pas encore tirée par de nombreux usages qui donnent des avantages business mesurables, et qu&apos;en dépit de ça elle et est présentée comme une future révolution qui sera utilisable dans presque tous les domaines à l&apos;aune de son &quot;potentiel&quot;, je préfère ne pas y consacrer trop de temps et me remémorer la morale de la fable du corbeau et du renard :

&gt; Apprenez que tout flatteur
&gt; Vit aux dépens de celui qui l&apos;écoute :
&gt; Cette leçon vaut bien un fromage, sans doute.

Je pense aussi à l&apos;article &quot;A radical idea&quot; de Jürgen Geuter. Il y partage une idée assez extrême, qu&apos;on pourrait prendre pour un conseil :

&gt; Things that do not exist (yet) do not exist.

Pour donner un peu plus de contexte :

&gt; We are constantly asked to keep talking about things as potential. To judge things based on promises of what they might do that go way beyond the actual realities of the thing. Like OpenAI and others can’t make any money with their machine learning models. But their text and image generators might bring a 10% GDP increase as Meta’s open letter claims? You sure about that?  Sounds like that requires a lot of magic thinking between 1) “OpenAI builds stochastic parrots” and 3) “GDP goes up by 10%”. How exactly is 2) shaped in this chain of reasoning and does it actually exist?

=&gt; https://tante.cc/2024/09/23/a-radical-idea/ A radical idea

Bref, je n&apos;ai pas de boule de cristal et je m&apos;autorise à me tromper, mais je pense que l&apos;IA générative ne sera pas la révolution annoncée.

=&gt; https://mastodon.social/@sroccaserra/112592922678941928 🧵 @sroccaserra
            </description>
            <pubDate>2024-06-10</pubDate>
            <guid>gemini://sroccaserra.fr/articles/2024-06-10_ia_generative_-_pas_encore_une_revolution.gmi</guid>
        </item>
        <item>
            <title>Do the right thing, do the thing right = ??</title>
            <link>gemini://sroccaserra.fr/articles/2024-06-03_do_the_right_thing_do_the_thing_right.gmi</link>
            <description>Dans une discussion avec des collègues, on a abordé un dicton qu&apos;on lit ou qu&apos;on entend souvent :

&gt; Do the right thing, do the thing right.

On a discuté sur les sens possibles de ce dicton, et quelqu&apos;un se demandait si il n&apos;invitait pas à commencer par faire quelque-chose qui fonctionne, sans se soucier de comment c&apos;est fait, et s&apos;inquiétait même d&apos;une possible invitation à faire vite et mal, en reportant le fait de rendre le code maintenable à &quot;un jour quand on aura le temps&quot;.

On a aussi évoqué le parallèle avec une pratique comme TDD (Test-Driven Development), qui nous invite à suivre un cycle &quot;red &gt; green &gt; refactor&quot;.

Et c&apos;est proche d&apos;un autre dicton, qu&apos;on retrouve dans les mondes Unix et Extreme Programming :

&gt; Make it work, make it right, make it fast.

Voilà ce que ce dicton, &quot;do the right thing, do the thing right&quot; évoque pour moi en général, et que j&apos;ai pris le temps de noter à cette occasion.

En effet, si on observe beaucoup de projets où on n&apos;a pas le temps de penser à &quot;do the thing right&quot;, on peut se demander si ce dicton est une bonne chose, et s&apos;inquiéter que si on s&apos;arrête au milieu du gué, on ne prendra pas le temps de faire &quot;the thing right&quot;.

Cependant, pour moi ce dicton n&apos;invite pas du tout à faire vite et mal, et je pense qu&apos;il n&apos;est pas du tout suivi sur les projets qui perdent le contrôle de leur base de code.

La première chose à laquelle j&apos;ai pensé, c&apos;est que &quot;do the right thing, do the thing right&quot; ne dit rien sur la vitesse. Donc ce n&apos;est pas forcément &quot;le plus vite possible&quot;. On peut tout à fait imaginer que justement, on va prendre le temps de s&apos;intéresser à &quot;comment la saucisse est faite&quot;.

On trouve un parallèle avec une pratique comme TDD. Quand on choisit de faire du TDD, on va effectivement commencer par écire un test qui ne passe pas, mais qui exprime notre intention (&quot;red&quot;), puis le faire passer le plus simplement possible (&quot;green&quot;), même si c&apos;est objectivement fait n&apos;importe comment. Et donc ça va vite, parce-qu&apos;en plus le test couvre une toute partie de la fonctionnalité. On parle même de &quot;micro test&quot; et j&apos;aime bien cette expression.  Et ensuite on commence à réfléchir, une fois que le test passe, sur toutes les façons dont on pourrait améliorer notre implémentation (&quot;refactor&quot;).  Et on l&apos;améliore dans la foulée.

Comme c&apos;est un micro test, tout ça ne prend que quelques minutes à quelques dizaines de minutes max. Donc à la fin de la journée, on n&apos;est pas censé avoir du code moche, puisqu&apos;on l&apos;améliore au fil de l&apos;eau. Le cycle &quot;right thing&quot; &quot;thing right&quot; est très très rapide, donc on n&apos;est pas censé retarder &quot;thing right&quot;.

En agilité on suit la même idée, d&apos;où l&apos;importance du feedback très rapide. Et c&apos;est souvent là que ça pèche en premier d&apos;expérience. Quand on commence à allonger le feedback, on perd l&apos;agilité.

L&apos;image que j&apos;aime bien pour faire ressentir cette idée, c&apos;est qu&apos;on préfère gérer nos projets comme une cuisine que comme un garage.

Quand on fait un peu de cuisine, on se rend compte tout de suite que si on accumule les ustensiles pas lavés et pas rangés, ça ne va pas le faire. Donc on alterne tâches / lavage / rangement. Pendant qu&apos;on fait revenir les oignons, on lave la planche à découper, etc. Tout est entremêlé, mais c&apos;est ce qui nous permet de continuer à travailler, on veut en permanence avoir un plan de travail utilisable.

Par contre, le garage, bon, on y met les raquettes de tennis, la petite table basse qu&apos;on n&apos;utilise plus, les jeux de société qui ne servent plus, le tapis du grand père, tout s&apos;accumule. Et une fois par an si on a le courage, on se dit &quot;allez, aujourd&apos;hui je range le garage&quot;. Et ça nous prend des heures, voir plusieurs jours, et on n&apos;aime pas ça. 

Donc &quot;do the right thing, do the thing right&quot; et autres, ça marche bien si on le fait dans une cuisine, avec alternance rapide. Et ça commence à coincer quand on accumule les améliorations à faire plus tard, on se retrouve avec le garage à ranger.

Pour revenir à la vitesse, on peut développer très lentement avec un rythme de feedback très rapide. C&apos;est en général le &quot;rythme du feedback&quot; que je préfère accélérer, pas le &quot;rythme de développement&quot;. On pourrait imaginer que si on accélère le feedback, le rythme de dev sera aussi amélioré. Probablement, mais c&apos;est un effet secondaire pour moi, et surtout je ne sais pas le mesurer. Ce qui est plus probable et souhaitable, c&apos;est qu&apos;en améliorant le feedback, on évitera de faire tellement de choses inutiles qu&apos;il sera évident qu&apos;on a choisi le bon chemin. Parfois c&apos;est difficile à voir cependant, car comme sur nos projets on veut toujours aller plus vite que la musique (mon interprétation), on se sent toujours en retard quoi qu&apos;on fasse (mon ressenti).

En tout cas, alterner &quot;do the right thing&quot; et &quot;do the thing right&quot; à un bon rythme est la meilleure façon de développer du logiciel que je connaisse, et c&apos;est ma préférence.

## Liens

=&gt; http://wiki.c2.com/?MakeItWorkMakeItRightMakeItFast
            </description>
            <pubDate>2024-06-03</pubDate>
            <guid>gemini://sroccaserra.fr/articles/2024-06-03_do_the_right_thing_do_the_thing_right.gmi</guid>
        </item>
        <item>
            <title>Injection de Dépendances</title>
            <link>gemini://sroccaserra.fr/articles/2024-04-11_Injection_de_Dépendances.gmi</link>
            <description>L&apos;injection de dépendances, c&apos;est à la fois simple et compliqué.

C&apos;est simple car on voit souvent l&apos;idée que : &quot;c&apos;est juste passer les dépendances en paramètre du constructeur&quot;. Et dans un sens, &quot;c&apos;est pas faux&quot;.

Les choses commencent à se compliquer quand on essaie de la définir. Une définition pourrait être par exemple :

&gt; On appelle &quot;Injection de Dépendances&quot; un ensemble de principes et de patterns
&gt; logiciels qui permettent de développer du code faiblement couplé.

Et quand on commence à vouloir utiliser ces principes et patterns dans notre code, on commence à se poser plusieurs questions. Par exemple :

* À quoi ça ressemble concrètement ?
* Qui est responsable d&apos;injecter ces dépendances ?
* À quel moment est-ce que j&apos;injecte mes dépendances ?
* Où est-ce que je vais instancier ces dépendances ?
* Est-ce que je suis obligé de passer par un framework ?
* Quelle est la différence entre Injection de Dépendances et Inversion de Dépendances ?
* Quels sont les patterns classiques ?
* Est-ce qu&apos;il y a des anti-patterns ?

Donc c&apos;est aussi potentiellement un peu compliqué.

J&apos;ai récemment lu le livre [Dependency Injection: Principles, Practices, and Patterns][di], de Stephan van Deursen et Mark Seemann. Ce livre apporte beaucoup de réponses, et j&apos;ai été surpris et très intéressé par la richesse du sujet.

Pour partager une petite partie de ce que j&apos;ai vu, je propose de regarder l&apos;exemple de code du livre, décrit en détail dans le chapitre 3. À chaque étape, j&apos;essaierai de mettre en valeur quelques points qui m&apos;ont particulièrement intéressé.

Note : cet article sera sans doute beaucoup plus intéressant si vous avez déjà quelques notions sur l&apos;injection de dépendances. Si vous voulez en savoir plus, vous pouvez commencer par lire l&apos;article Inversion of Control Containers and the Dependency Injection pattern de Martin Fowler.

=&gt; https://martinfowler.com/articles/injection.html Inversion of Control Containers and the Dependency Injection pattern

Note : l&apos;exemple est en C#, mais les principes appliqués devraient fonctionner quel que soit le langage et le framework. Ici le choix est fait de ne pas utiliser de container d&apos;injection de dépendance, afin de bien voir toutes les parties.

Avertissement / Disclaimer : ce qui suit est un exemple qui illustre très bien de nombreux points mais ce n&apos;est pas &quot;the only true way&quot; pour gérer les dépendances. Si vous avez d&apos;autres façons de faire, si vous utilisez le framework X ou Y, c&apos;est très bien, voyez ce qui fonctionne pour vous.  L&apos;important est que vous ayez une bonne compréhension de vos pratiques et de ce qu&apos;elles vous apportent.

## La fonctionnalité

L&apos;exemple décrit une fonctionnalité d&apos;un site d&apos;e-commerce. Cette fonctionnalité consiste à afficher une liste de *featured products* (produits phares) avec leurs prix. Si le client connecté est un *preffered customer* (client privilégié), alors il a droit à un *discount* (rabais) de 5 % sur ces *featured products* et les prix affichés doivent tenir compte de ce rabais.

Exemple de résultat attendu (imaginer une vue en joli HTML ici):

```
Featured Products

- Criollo Chocolate ($34.95)
- Gruyère ($48.50)
- White Asparagus ($39.80)
- Anchovies ($18.75)
- Arborio Rice ($22.75)
```

## La vue

Je vais commencer à décrire tout le code en commençant par la vue. Ce n&apos;est pas très intéressant tout de suite, mais ça permet de bien voir l&apos;ensemble en partant de l&apos;aspect visible de la fonctionnalité.

Les parties en gras font le lien d&apos;un bout de code à l&apos;autre.

```cshtml
@* src/Commerce.Web/Views/Home/Index.cshtml *@
@model FeaturedProductsViewModel

&lt;h2&gt;Featured Products&lt;/h2&gt;
&lt;ul&gt;
    @foreach (ProductViewModel product in this.Model.Products)
    {
        &lt;li&gt;@product.SummaryText&lt;/li&gt;
    }
&lt;/ul&gt;
```

Ci dessus, à la ligne 6 on voit qu&apos;on itère sur des `ProductViewModel` pour afficher une liste de `SummaryText` ligne 8. Je note aussi la notion de &quot;ViewModel&quot; : c&apos;est un modèle dédié à la vue. Comme on l&apos;a vu dans la liste de Featured Products du résultat attendu, ces `SummaryText` montrent un nom et un prix. Voyons d&apos;où viennent ces informations.

```cs
// src/Commerce.Web/Models/ProductViewModel.cs
public class ProductViewModel
{
    private static CultureInfo PriceCulture = new CultureInfo(&quot;en-US&quot;);

    public ProductViewModel(DiscountedProduct product)
    {
        this.SummaryText = string.Format(PriceCulture,
            &quot;{0} ({1:C})&quot;, product.Name, product.UnitPrice);
    }

    public string SummaryText { get; }
}
```

Ligne 6, le ProductViewModel est construit à partir d&apos;un `DiscountedProduct`, et c&apos;est ce `ProductViewModel` qui a la responsabilité de construire le `SummaryText` visible par l&apos;utilisateur à partir du nom et du prix unitaire du `DiscountedProduct` (lignes 8-9).

Ça va commencer à devenir intéressant, descendons dans le controller qui traite la requête pour voir qui nous fournit ces `DiscountedProducts`.

## Le controller

```cs
// src/Commerce.Web/Controllers/HomeController.cs
public class HomeController : Controller
{
    private readonly IProductService productService;

    public HomeController(
        IProductService productService)  // 1) Dépendance au service injectée
    {
        if (productService == null)
            throw new ArgumentNullException(
                &quot;productService&quot;);

        this.productService = productService;
    }

    public ViewResult Index()
    {
        IEnumerable&lt;DiscountedProduct&gt; products =
            this.productService.GetFeaturedProducts();  // 2) Récupération des DiscountedProduct

        var vm = new FeaturedProductsViewModel(
            from product in products
            select new ProductViewModel(product));  // 3) Instanciation des ProductViewModel

        return this.View(vm);
    }
}
```

Comme on le voit ligne 19, c&apos;est un `IProductService` qui a la responsabilité de fournir la liste des `DiscountedProducts` au controller (2). Cet IProductService est injecté dans le controller dès la construction, ligne 7 (1). C&apos;est un exemple d&apos;injection de dépendance par paramètre de constructeur, un pattern classique.

On voit aussi que le controller a la responsabilité de créer les `ProductViewModels` passés à la vue, ligne 23 (3).

Allons voir en quoi consiste cet `IProductService`.

## Le service

Le `IProductService` est ici ce qu&apos;on appelle parfois un *Application Service*. Cette notion d&apos;*Application Service* est parfois connue sous d&apos;autre nom, l&apos;important c&apos;est que c&apos;est un point d&apos;entrée de la couche métier, souvent avec un rôle d&apos;orchestration. Pour nommer cette couche métier, on entend souvent parler de *Domain*, de *Business Logic*, de *Use Cases* en fonction du vocabulaire que vous avez choisi dans votre équipe.

```cs
// src/Commerce.Domain/IProductService.cs
public interface IProductService
{
    IEnumerable&lt;DiscountedProduct&gt; GetFeaturedProducts();
}
```

L&apos;*application service*, c&apos;est avant tout l&apos;interface `IProductService` ci-dessus, une liste de méthodes publiques. Le `HomeController` n&apos;a pas à en savoir plus, et ne doit pas dépendre de l&apos;implémentation du service. Mais comme on veut faire tout le chemin, allons observer cette fameuse implémentation.

```cs
// src/Commerce.Domain/ProductService.cs
public class ProductService : IProductService
{
    private readonly IProductRepository repository;
    private readonly IUserContext userContext;

    public ProductService(
        IProductRepository repository,  // 1) Dépendances, injectées par constructeur
        IUserContext userContext)
    {
        if (repository == null)
            throw new ArgumentNullException(&quot;repository&quot;);
        if (userContext == null)
            throw new ArgumentNullException(&quot;userContext&quot;);

        this.repository = repository;
        this.userContext = userContext;
    }

    public IEnumerable&lt;DiscountedProduct&gt; GetFeaturedProducts()
    {
        return
            from product in this.repository
                .GetFeaturedProducts()                // 2) récupération des produits phares
            select product
                .ApplyDiscountFor(this.userContext);  // 3) application des rabais en fonction du userContext
    }
}
```

Il y a trois points à observer ici.

On peut voir à nouveau en 1) de l&apos;injection de dépendances par paramètres de constructeur.

On peut voir également en 2) la récupération des featured products à partir d&apos;un repository.

Et en 3) on peut voir un élément moins courant, le passage d&apos;un userContext à la méthode `ApplyDiscountFor()` de l&apos;entité `Product`. On verra le détail de cette méthode plus bas. Pour le moment, on peut noter que ce `IUserContext` est également injecté dans le service au niveau du constructeur, ligne 9.

Comme on le verra plus bas, ce `IUserContext` est résolu et injecté à chaque requête.

## L&apos;entité Product et l&apos;objet DiscountedProduct

On peut observer ici un exemple d&apos;entité qui porte des responsabilités métier, comme appliquer un *discount*. Ce n&apos;est pas un simple sac de données.

```cs
// Product Entity
// src/Commerce.Domain/Product.cs
public class Product
{
    public string Name { get; set; }
    public decimal UnitPrice { get; set; }
    public bool IsFeatured { get; set; }

    public DiscountedProduct ApplyDiscountFor(  // 1) Application d&apos;un rabais
        IUserContext user)                      // 2) Injection de contexte par méthode
    {
        bool preferred =
            user.IsInRole(Role.PreferredCustomer);  // 3) Utilisation du contexte pour déterminer si l&apos;utilisateur est &quot;preferred&quot;

        decimal discount = preferred ? .95m : 1.00m;

        return new DiscountedProduct(               // 4) Construction d&apos;un autre type
            name: this.Name,
            unitPrice: this.UnitPrice * discount);
    }
}
```

Il y a à nouveau beaucoup de choses intéressantes ici.

1) Comme dit plus haut, cette entité sait faire des choses, comme appliquer un *discount*.

2) Pour appliquer ce *discount*, l&apos;entité a besoin du contexte utilisateur, qui est variable et peut changer à chaque requête. Ce contexte est injecté par méthode, c&apos;est un pattern moins discuté que l&apos;injection par constructeur, mais très pertinent ici. C&apos;est pertinent ici car l&apos;injection par constructeur ne va pas fonctionner : on ne veut pas avoir besoin de connaître des choses sur l&apos;utilisateur connecté au moment de la construction des entités `Product`, qui a probablement lieu dans une implémentation de *product repository*.

3) Ici l&apos;entité pose une question au contexte, elle ne dépend pas de sa structure interne. &quot;Est-ce que l&apos;utilisateur est preffered ?&quot; Ce qui veut dire qu&apos;on peut changer la structure interne du UserContext sans avoir à changer l&apos;entité.

4) Appliquer un *discount* ne modifie pas l&apos;entité Product, mais crée un nouvel objet de type &quot;DiscountedProduct&quot;, qu&apos;on va voir ci-dessous.

```cs
// DiscountedProduct POCO class
// src/Commerce.Domain/DiscountedProduct.cs
public class DiscountedProduct
{
    public DiscountedProduct(string name, decimal unitPrice) {
        if (name == null) throw new ArgumentNullException(&quot;name&quot;);

        this.Name = name;
        this.UnitPrice = unitPrice
    }

    public string Name { get; }
    public decimal UnitPrice { get; }
}
```

Cet objet `DiscountedProduct` est lui un sac de données. C&apos;est un objet d&apos;échange. C&apos;est lui qui est passé à la vue, qui l&apos;utilise pour produire ses `SummaryText` comme on l&apos;a vu plus haut.

## Le IUserContext

Voyons maintenant un exemple simple d&apos;implémentation de `IUserContext`.

```cs
// src/Commerce.Domain/IUserContext.cs
public interface IUserContext
{
    bool IsInRole(Role role);
}

// src/Commerce.Domain/Role.enum.cs
public enum Role { PreferredCustomer }
```

C&apos;est avant tout une interface, avec des méthodes publiques. Ici, une méthode publique, `IsInRole()`. Cette méthode a la responsabilité de dire si l&apos;utilisateur possède tel ou tel rôle. En passant, les rôles sont définis par exemple par une enum, pourquoi pas.

Comme on le voit ci-dessous, l&apos;implémentation nécessitera une adaptation vers le framework.

## UserContext et adaptation vers le Framework

Dans cet exemple en ASP.NET, une façon d&apos;implémenter ce UserContext est d&apos;utiliser le `HttpContextAccessor` fourni par le framework. Le framework nous dit que cet objet connait les rôles de l&apos;utilisateur dans le contexte de la requête. Ici c&apos;est un peu magique à mon goût mais je fais confiance au framework. Par exemple :

```cs
// src/Commerce.Web/AspNetUserContextAdapter.cs
public class AspNetUserContextAdapter : IUserContext
{
    private static HttpContextAccessor Accessor = new HttpContextAccessor();

    public bool IsInRole(Role role)
    {
        return Accessor.HttpContext.User.IsInRole(role.ToString());
    }
}
```

On voit que pour le framework, les rôles sont des strings, et qu&apos;on a choisi une enum plus haut. C&apos;est très bien, l&apos;adaptation est faite ici, et on ne se plie pas aveuglément aux choix du framework.

On voit aussi que cette adaptation nécessitera de bien connaître votre framework, et peut-être d&apos;adapter les choses à votre cas.

La dernière étape sera de voir comment tout ça se connecte : comment est-ce qu&apos;on va brancher toutes ces dépendances ?

## Composition Root

C&apos;est bien beau toutes ces dépendances, mais on n&apos;a pas encore vu comment tout se branche concrètement.

Un des patterns important du livre est la notion de *Composition Root*. C&apos;est dans le Composition Root que le graphe de toutes les dépendances qu&apos;on a vues jusqu&apos;ici est enfin résolu.

Si on utilise un container d&apos;injection de dépendance, cette résolution sera faite pour vous. Mais comme on le voit ci-dessous, on n&apos;est pas obligé d&apos;utiliser un container, une résolution KISS peut aussi fonctionner.

Ici on observe ce qui se passe dans notre implémentation du `IControllerActivator`, interface du framework qui est au bon endroit pour servir de *Composition Root*.

```cs
// The application&apos;s object graph
// more or less in the IControllerActivator.Create() method

// src/Commerce.Web/CommerceControllerActivator.cs
new HomeController(
    new ProductService(
        new SqlProductRepository(
            new CommerceContext(connectionString)),
        new AspNetUserContextAdapter()));
```

On peut voir explicitement comment les dépendances sont injectées, un peu comme des poupées russes. Le `HomeController`, le `ProductService`, le `SqlProductRepository` (`IProductRepository`), et le `AspNetUserContextAdapter` (`IUserContext`).

Note : je n&apos;ai pas décrit l&apos;implémentation du IProductRepository, car c&apos;est souvent quelque-chose qui est connu et que l&apos;article est déjà très long.

Il y a quelques finesses qui méritent d&apos;être soulignées avant de terminer ce tour d&apos;horizon.

Tout d&apos;abord, il est important que ce graphe soit résolu à un seul endroit, le *Composition Root*. Si on rend les dépendances disponibles dans tout le code, et qu&apos;à n&apos;importe quel endroit du code on peut accéder à une dépendance par une forme de *Registry* ou de *ServiceLocator*, on va avoir le même problème que quand on utilise des variables globales : potentiellement, tout peut dépendre de tout, et le code devient très difficile à changer avec confiance.

Ensuite, la résolution est faite au plus près possible du point d&apos;entrée de l&apos;application. Ici, dès qu&apos;une requête arrive, on instancie tout et les dépendances sont branchées pour tout le reste de l&apos;exécution de la requête.

Note : on pourrait avoir peur pour les performances si on résout tout à chaque requête, mais en pratique c&apos;est rarement un problème. Si vous mesurez que dans votre cas c&apos;est effectivement un problème, le livre propose des solutions mais je ne rentre pas dans ce détail.

## Pour aller plus loin

Pour aller plus loin, on pourrait observer que certaines dépendances sont stables, et ne nécessitent pas d&apos;être injectées. Le livre parle de *stable dependencies* et de *volatile dependencies*. Ce sont les dépendances volatiles qui nécessitent d&apos;être injectées.

Une dépendance est &quot;volatile&quot; quand elle n&apos;est pas toujours disponible (bases de données, services Web, ...), quand elle contient un comportement non déterministe (temps, ...) ou qu&apos;elle a besoin d&apos;être remplacée, encapsulée, ou interceptée (il reste peu de choses ici normalement une fois qu&apos;on a vu les deux premiers groupes).

On pourrait aussi chercher si dans le *Composition Root* il n&apos;y a pas une partie configuration des dépendances, et une partie résolution. Un pattern possible est de séparer configuration et résolution, en mettant la configuration dans un fichier par exemple. Typiquement, la configuration est faite au démarrage de l&apos;application, et la résolution peut se faire à chaque requête.

On peut également s&apos;intéresser à comment utiliser notre framework ou un container d&apos;injection de dépendances, maintenant qu&apos;on a vu une façon de faire un peu complète.

Je vous invite à consulter le livre [Dependency Injection][di] ou le blog de Mark Seemann pour en savoir plus sur ces patterns.

## Conclusion

C&apos;est terminé, on a enfin bouclé ce très grand tour qui nous montre concrètement à quoi peut ressembler en pratique notre injection de dépendances.

On a vu le pattern classique &quot;injection par paramètre de constructeur&quot;, le pattern moins discuté &quot;injection par paramètre de méthode&quot;, on a même observé une entité métier qui est responsable d&apos;un comportement.

On a également vu &quot;quand&quot; est faite l&apos;injection, et une version naïve de &quot;comment&quot; est faite l&apos;injection, avec cette notion de *Composition Root*.

Rien n&apos;est particulièrement compliqué, mais je trouve intéressant de récapituler comment tout ça peut fonctionner ensemble, c&apos;est souvent ce qui manque aux exemples qui ne montrent qu&apos;une seule partie.

## Liens

=&gt; https://www.manning.com/books/dependency-injection-principles-practices-patterns Le livre Dependency Injection: Principles, practices, and Patterns
=&gt; https://github.com/DependencyInjection-2nd-edition/codesamples/tree/master/RightECommerce L&apos;exemple de code, en un peu plus détaillé
=&gt; https://blog.ploeh.dk/ Le blog de Mark Seemann
=&gt; https://blog.ploeh.dk/tags/#Dependency%20Injection-ref Les nombreux articles sur l&apos;injection de dépendances dans son blog
=&gt; https://fsharpforfunandprofit.com/posts/dependencies/ Les articles de Scott Wlaschin sur l&apos;injection de dépendances en programmation fonctionnelle
            </description>
            <pubDate>2024-04-11</pubDate>
            <guid>gemini://sroccaserra.fr/articles/2024-04-11_Injection_de_Dépendances.gmi</guid>
        </item>
        <item>
            <title>Cycle de vie et abstraction</title>
            <link>gemini://sroccaserra.fr/articles/2024-02-13_Cycle_de_vie_et_abstraction.gmi</link>
            <description>Je refais un peu de C++ en feuilletant la troisième édition de &quot;A Tour of C++&quot;, et j&apos;aime bien. C&apos;est amusant, car j&apos;ai fait beaucoup de C++ en début de carrière et j&apos;en avais gardé un souvenir peu ému, je me souvenais surtout des footguns. Il a même dû m&apos;arriver d&apos;en dire du mal quand j&apos;en avais l&apos;occasion.  Aujourd&apos;hui, je suis à nouveau intéressé par ce que j&apos;ai appris grâce à ce langage. J&apos;ai l&apos;impression que mes opinions suivent des phases.

Dans les choses que j&apos;ai apprises, je suis content d&apos;en avoir fait suffisamment à l&apos;époque pour éviter les `new` et avoir en tête RAII, ça semble encore pertinent en C++ moderne.

Je note aussi que le principe RAII (Resource Acquisition Is Initialization) m&apos;a donné le goût de la symétrie dans le cycle de vie.  J&apos;apprécie que la création d&apos;un objet et sa destruction / sortie de scope, ou que les ouvertures et fermetures de ressources aient lieu au même niveau d&apos;abstraction, et si possible dans des positions symétriques.

Je repense souvent à ce principe, même dans des langages où on ne gère pas explicitement la mémoire. Pour essayer de le décrire, souvent il y a des traitements qui peuvent bien se modéliser en poupées gigognes de :

* &quot;préparation&quot;
* &quot;exécution&quot;
* &quot;conclusion&quot;

La préparation et la conclusion pouvant être symétriques et au même niveau d&apos;abstraction. Et la phase exécution pouvant être une descente dans le niveau d&apos;abstraction qui à son tour peut se modéliser comme une &quot;préparation&quot; / &quot;exécution&quot; / &quot;conclusion&quot; (avec des tortues jusqu&apos;en bas).

J&apos;apprécie ce genre de mini patterns, ça m&apos;aide souvent à structurer ma pensée. Je le perçois comme du &quot;micro-design&quot; (nom inspiré des &quot;microtests&quot;, un nom que je préfère à Unit Test). Un autre exemple connu auquel je pense aussi comme du &quot;micro-design&quot; est les Four Elements of Simple Design (voir liens ci-dessous).

Autre exemple : en plissant les yeux on peut voir le pattern Functional Core, Imperative Shell comme un pattern &quot;préparation&quot; / &quot;exécution&quot; (fonctionnelle pure) / &quot;conclusion&quot;.

=&gt; https://mastodon.social/@sroccaserra/111924533437429454 🧵 @sroccaserra

## Liens

=&gt; https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization
=&gt; https://www.stroustrup.com/tour3.html
=&gt; https://en.wikipedia.org/wiki/Turtles_all_the_way_down
=&gt; http://anarchycreek.com/2009/05/20/theyre-called-microtests/
=&gt; https://blog.jbrains.ca/permalink/the-four-elements-of-simple-design
=&gt; https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell
            </description>
            <pubDate>2024-02-13</pubDate>
            <guid>gemini://sroccaserra.fr/articles/2024-02-13_Cycle_de_vie_et_abstraction.gmi</guid>
        </item>

    </channel>
</rss>
