Les design patterns expliqués par un (piètre) dessinateur.


Patrons de conception : solutions clef en main pour résoudre des problèmes d’architecture logicielle. Ils sont plus connus sous le nom de Design Patterns.


Vous avez dit design ?

Récemment, je me suis mis au dessin. Je suis encore loin d’être le nouveau De Vinci, mais ça m’amuse et je progresse de jour en jour 😊

Mais je me suis rendu compte d’un truc assez surprenant : le dessin partage beaucoup de choses avec la programmation.

Typiquement, les deux sont très simples à apprendre.

Un débutant peut commencer à produire des dessins ou des applications en quelques semaines, ce qui n’est pas le cas pour toutes les disciplines (architecture, ingénierie…).

Mon premier gros dessin après à peine deux semaines (~10h d’apprentissage), je ne savais même pas dessiner un pauvre cercle avant ça !

Les bases sont certes simples à acquérir, mais la difficulté vient avec la complexité.

N’importe qui peut dessiner des formes ou écrire des fonctions, mais les assembler dans un tout propre et cohérent, c’est extrêmement compliqué.

Et malheureusement, peu de gens savent faire ça correctement, dessinateurs comme développeurs.

La raison, c’est que c’est beaucoup simple de créer des choses telles qu’on les voit.

Par exemple, le réflexe d’un néophyte lorsqu’il veut dessiner un bâtiment, c’est de l’observer et de le recopier, ligne par ligne.

Pareil, pour implémenter une exigence client, il suffit de lire le cahier des charges et de coder le tout, composant par composant.

Cool, on met les mains dans le cambouis sans perdre une seule seconde, mais on ne prend pas le temps de voir la grande image de ce qu’on va réaliser.

Et bien souvent, c’est une fois le travail terminé que l’on réalise qu’on a fait une grosse connerie.

Combien de fois mon cœur s’est-il brisé en voyant la sale gueule du personnage que j’ai passé 30m à dessiner ?

Mes sens visuels strictement humains m’indiquent un petit problème de proportion…

Et combien de journées perdues à écrire du code vraiment pourri sans même m’en rendre compte ?

Pourtant, j’ai fait des efforts. Mes composants étaient bien nommés, bien commentés, les fonctions étaient courtes et respectaient le principe de responsabilité unique. Bref, à priori, du code de premier choix.

Mais le vrai problème se trouvait au niveau de la relation entre les composants, invisible lorsqu’on a la tête dans le guidon.

Ce n’est pas qu’une simple mauvaise pratique, c’est un problème architectural. La réalisation est parfaite, mais la réflexion est mauvaise.

Et l’impact est absolument dramatique.

Imaginez, c’est comme si l’architecte de votre maison avait monté la porte de vos toilettes à l’envers. Allez réparer une connerie pareille sans tout péter !

Sur une codebase, c’est la même chose, c’est difficile de faire machine arrière sans effacer votre précieux travail et recommencer.

Tant pis, foutu pour foutu, autant passer à autre chose.

Surtout pas !

Car ça génère une dette technique tellement énorme que le jour où vous allez devoir maintenir cette partie du système, ça va vous prendre des heures, et une bonne dose de XANAX.

Et plus vous allez attendre, plus ça s’aggravera.

Le syndrome du peintre qui se bloque dans un coin. Image de freepik.com.

Ouvrez vos chakras

Ça va vous surprendre, mais un artiste ne dessine pas vraiment ce qu’il voit, mais ce qu’il perçoit.

Il a une manière de penser radicalement différente que celle d’un amateur. Prenez ce dessin par exemple :

Facile, non ? Pourtant, essayez de le recopier, vous verrez que c’est beaucoup plus difficile que ça en a l’air.

Mais pas pour un artiste, car il saurait immédiatement comment approcher ce genre de problème. Regardez plutôt :

J'ai simplement placé 3 points, tracé des lignes (grises) et relier en noir les points où les lignes se croisent.

D’un coup, ça devient beaucoup plus facile. Et tous les dessins reposant sur des perspectives peuvent être imaginés de cette manière.

Ce n’est que de l’astuce, une sorte de patron qui permet de mieux conceptualiser le dessin avant de le réaliser. Tiens, tiens, ça ne vous rappelle pas quelque chose ?

Ce concept existe aussi en programmation.

Il s’agit de solutions génériques permettant de définir la manière dont les différents composants d’un programme vont s’agencer entre eux et former un tout robuste et flexible.

Ils permettent de :

Tout ça dans le but de limiter un maximum la dette technique d’un programme, et donc garantir sa maintenance, son évolution et sa pérennité.

Les patrons de conception sont le B A BA de l’architecture logiciel. Vous ne pouvez pas designer correctement une codebase si vous ne les connaissez pas !


Joujou pour architectes

Génial, moi aussi j’ai envie de devenir architecte ! Du coup, où est-ce qu’on télécharge ça ?

Nulle part. En réalité, ce ne sont même pas des choses concrètes (comme des frameworks), mais des idées abstraites.

C’est comme pour le dessin. Quand j’ai fait mes perspectives, je n’ai pas utilisé d’outil hormis ce que j’avais sous la main : un crayon et une règle (et 2 couleurs).

Ça veut dire que peu importe le support, vous pouvez utiliser cette technique : papier, ordinateur, iPad, mur, crâne chauve de votre père, peu importe.

Niveau perspectives, difficile de faire mieux. Image de freepik.com

Les patrons de conception ne sont que des cas d’utilisation des règles d’un paradigme de programmation (orientée objet, fonctionnel, procédural…), et c’est à vous de les implémenter.

Donc en gros, on peut les utiliser sans outil supplémentaire, quel que soit le langage ou le framework ?

C’est ça.

Prenons l’exemple d’un des plus simples : l’injection de dépendance.

Le principe, c’est qu’au lieu d’avoir un objet qui construit lui-même ses dépendances, on les construit à l’extérieur et on les passe toutes prêtes à son constructeur.

Avant : un constructeur de fous furieux, qui initialise tout de A à Z.
Après : les objets sont construits à l’extérieur, et le constructeur est tout petit.

Vous remarquez que ça parle d’objet et de constructeurs, mais rien de vraiment spécifique, car ce patron est implémentable dans tous les langages orientés objet. La preuve :

public class Drawing
{
    private Author author;
    private Pencil pencil;

    public Drawing(Author author, Pencil pencil)
    {
        this.author = author;
        this.pencil = pencil;
    }
}
En Java
<?php

class Drawing
{
    private $author;
    private $pencil;

    public function __construct(Author $author, Pencil $pencil)
    {
        $this->author = $author;
        $this->pencil = $pencil;
    }
}
En PHP
public class Drawing
{
    private Author Author { get; set; }
    private Pencil Pencil { get; set; }

    public Drawing(Author author, Pencil pencil)
    {
        Author = author;
        Pencil = pencil;
    }
}
En C#

Penser en mode patron

Du coup, quand est-ce qu’il faut les utiliser ?

Les patrons de conception ont été imaginés pour résoudre des problèmes de programmation. Tant qu’il y a des problèmes, ils sont pertinents.

Il est important de savoir penser en mode patron : identifier les problèmes et répondre avec un (ou plusieurs) patron de conception. Il y a 3 étapes clefs pour cela, que j’ai classé par ordre de difficulté :

  1. Phase de réusinage : une fois que le mal est fait, il est facile d’identifier ce qui aurait pu être amélioré, et remettre le système à neuf. Autrement dit, rembourser la dette technique.
  2. Phase de réalisation : savoir identifier les patrons de conception qui se cachent derrière une exigence client, afin de traduire son besoin en code propre et maintenable.
  3. Phase d’architecture : assembler les patrons de conception de manière à pouvoir faire face à n’importe quel changement d’exigence sereinement (Design Stamina Hypothesis), avant même d’avoir commencé à coder.

Une fois que vous aurez acquis ce réflexe, vous saurez attaquer les problèmes architecturaux à la source, et gagner en qualité de code considérable (même en phase 1).

C’est une des compétences qui fait la différence entre un développeur moyen et un développeur ultra-efficace.


Mais du coup, ça se passe comment dans le code ?

Difficile de répondre, car chaque patron de conception résout SON problème avec SA manière d’être implémenté. C’est du cas par cas.

D’où l’importance d’en connaitre un maximum sur le bout des doigts.

Malheureusement, il n’y a pas de « liste officielle » de tous les patrons existants, mais voici quelques pistes :

Ok, nickel, mais moi, je ne fais que des scripts d’importations de données. Est-ce que ce n’est pas un peu too much ?

Le principal défaut d’un patron de conception est qu’il complexifie une codebase (d’où l’intérêt de bien les documenter). Donc la question est légitime.

Pour y répondre, demandez-vous juste une chose : est-ce que votre code va évoluer ?

Si c’est juste un one shot et que vous n’y touchez plus après, ce n’est pas nécessaire.

Mais si la réponse est oui, faites-le, car on ne sait jamais ce qu’on va devoir ajouter ou modifier. Et quand on voit la gueule de certaines codebases, l’effort en vaut la chandelle.

En utilisant la même technique, j’ai pu ajouter une extension à ma forme sans aucun problème.

Voilà pour cette présentation survolée de ce que sont les patrons de conception. Je vous invite… Non, je vous ordonne de vous y intéresser plus en détail, c’est un des meilleurs services que vous pouvez vous rendre !

Et rien ne vaut de saines lectures. Je vous recommande donc vivement les livres suivantes :

Ainsi que les blogs suivants :


Merci d’avoir lu cet article jusqu’au bout, si le sujet vous intéresse, ne vous inquiétez pas, on va (beaucoup) en reparler.

Partagez cet article autour de vous pour faire connaitre ce noble concept à un maximum de gens. Et en plus, vous faites une bonne action en soutenant le blog 😊

Suivez-moi sur Twitter @ITExpertFr pour recevoir mes meilleurs conseils (et réflexions de douches) au quotidien.

Et pour les fanas d’architecture logicielle, j’ai quelques autres articles à vous mettre sous la dent :

Quant à moi, je vous laisse, je vais aller faire bronzette sur le toit de mon gratte-ciel à New York City.

À bientôt pour un nouvel article sur le blog des développeurs ultra-efficaces. Tchao !