Leçons de bonnes pratiques de codage : ne vous répétez pas

Written by | 31 January 2014 | Published in 2014 January
Je suis père. Cela sonne un peu comme une confession, mais ceux qui me connaissent savent que j’adore les enfants. Actuellement, j'en ai trois et j’espère bien en avoir d’autres dans un futur proche. Etre parent m’a énormément appris. J’ai notamment appris qu’il existe un étrange phénomène qui veut que mes enfants n’écoutent pas ce que je leur demande tant que je ne l’ai pas répété maintes et maintes fois. C’est intriguant car cela ne semble pas toujours être le cas. En effet, cela ne se produit que dans certains cas, et généralement lorsqu’ils doivent faire quelque chose qu’ils n’ont pas particulièrement envie de faire. C'est excessivement fatiguant et au bout d’un certain temps, cela devient véritablement pénible de toujours devoir me répéter.

Bien, maintenant vous vous demandez surement le rapport avec le codage et les meilleures pratiques de développement. Aujourd’hui, je souhaite aborder avec vous le concept du "Ne Vous Répétez Pas" (Don't Repeat Yourself - DRY).

Définition

Wikipedia définit le principe du "Ne vous répétez pas" comme suit :

Dans un système, toute connaissance doit avoir une représentation unique, non-ambiguë, faisant autorité.  

Reprenons cette définition en la décomposant afin d'en faciliter sa compréhension. Ensuite, nous l’appliquerons au code.

Toute connaissance : en développement, cela peut être une classe, une fonction, ou même un bloc de code à l’intérieur d’une fonction.
Une représentation unique, non-ambiguë, faisant autorité : un code ne devrait être présent qu’une seule et unique fois et devrait être écrit de façon claire.
Dans un système : dans votre composant, module, plugin, application, etc.

Si nous prenons ces fragments de texte et que nous réécrivons cette définition dans nos propres termes cela ressemblerait plutôt à ceci :

Tout code écrit et utilisé dans votre composant ne doit être présent qu’en un seul endroit et doit être clairement écrit.

Cela semble plus logique, non ? Maintenant que nous avons une bonne définition de travail de ce qu’implique le concept de "Ne Vous Répétez Pas", regardons quelques exemples d’application dans votre code.

Exemple de Mauvais Code

function getSingleItem($id) 
{
   // assume all variables needed
   $query = $this->db->getQuery(TRUE)
            ->select($this->db->quoteName(array('i.*', 'c.name', 'a.something')))
            ->from($this->db->quoteName('#__myitems', 'i'))
            ->join('LEFT', $this->db->quoteName('#__categories', 'c') . ' ON (' . 
              $this->db->quoteName('i.category_id') . ' = ' . $this->db->quoteName('c.category_id') . ')')
            ->join('LEFT', $this->db->quoteName('#__attributes', 'a') . ' ON (' .
              $this->db->quoteName('a.item_id') . ' = ' . $this->db->quoteName('i.item_id') . ')')
            ->where($this->db->quoteName('i.item_id') . ' = '. (int) $id);
   $this->db->setQuery($query);
   $item = $this->db->loadObject();
}
function getManyItems($ids) 
{ 
   // assume all variables needed 
   $query = $this->db->getQuery(TRUE) 
            ->select($this->db->quoteName(array('i.*', 'c.name', 'a.something'))) 
            ->from($this->db->quoteName('#myitems', 'i')) 
            ->join('LEFT', $this->db->quoteName('#categories', 'c') . ' ON (' . $this->db->quoteName('i.category_id') . ' = ' . 
              $this->db->quoteName('c.category_id') . ')') 
            ->join('LEFT', $this->db->quoteName('#__attributes', 'a') . ' ON (' . $this->db->quoteName('a.item_id') . ' = ' . 
              $this->db->quoteName('i.item_id') . ')') 
            ->where($this->db->quoteName('i.item_id') . ' IN '. implode(',', $ids)); 
    $this->db->setQuery($query); 
    $item = $this->db->loadObject(); 
}

Trouvez-vous ce code répétitif ? Certainement. J’ai créé la seconde fonction en recopiant la première puis je n’ai modifié qu'une seule ligne. (un indice ? regardez la clause 'where'). A quoi ressemblerait ce code si je le réécrivais sans dupliquer de lignes de code ?
Voici une possibilité.

Exemple d’un Meilleur Code

function getSingleItem($id) 
{ 
   // assume all variables needed 
   $query = $this->getQuery(); 
   $query->where($this->db->quoteName('i.item_id') . ' = '. (int) $id); 
   $this->db->setQuery($query); 
   $item = $this->db->loadObject(); 
}
function getManyItems($ids) 
{ 
   // assume all variables needed 
   $query = $this->getQuery(); 
   $query->where($this->db->quoteName('i.item_id') . ' IN '. implode(',', $ids));
   $this->db->setQuery($query);
   $item = $this->db->loadObject();
}
function getQuery() 
{ 
   $query = $this->db->getQuery(TRUE) 
            ->select($this->db->quoteName(array('i.*', 'c.name', 'a.something'))) 
            ->from($this->db->quoteName('#myitems', 'i')) 
            ->join('LEFT', $this->db->quoteName('#categories', 'c') . ' ON (' . $this->db->quoteName('i.category_id') . ' = ' . 
              $this->db->quoteName('c.category_id') . ')') 
            ->join('LEFT', $this->db->quoteName('#__attributes', 'a') . ' ON (' . $this->db->quoteName('a.item_id') . ' = ' . 
              $this->db->quoteName('i.item_id') . ')');
   
   return $query;
}

Au lieu d’écrire une seconde fois la fonction 'query' - une fois pour chaque fonction - j'ai extrait le code répété et j'ai écrit une troisième fonction que je peux désormais appeler à partir de l'une ou l'autre fonction. Cela semble simple. En fait, de nombreux développeurs mettent déjà en œuvre ce type de pratique afin d'optimiser leur code.

Les avantages

Pourquoi est-il si important de ne pas se répéter ?
Il existe de nombreux avantages à écrire votre code une seule fois. Bien sur, personne n’aime gaspiller son temps à écrire encore et encore le même code, mais plus important encore, vous diminuez les risques d’un bug. Moins de code signifiera toujours moins de possibilité de points de défaillance. Je suis sûr que, tout comme moi, vous avez déjà perdu une ou plusieurs heures à tenter d'élucider un problème pour finalement trouver LE point-virgule manquant. Je connais, cela m'arrive. Il y a également d'autres avantages. Lorsque vous vous apercevez par la suite que vous devez ajouter une autre table à la requête parce que votre client a besoin de plus d'informations en provenance de la base de données, il vous suffit désormais de mettre à jour une seule requête !

J’espère que nombre de développeurs sont déjà conscients de ce principe du "Ne Vous Répétez Pas". Si c’est un tout nouveau concept pour vous, félicitations, vous savez désormais ce que signifie écrire un "DRY (Don’t Repeat Yourself) code".
Je souhaitais débuter cette nouvelle série par un sujet simple, même si je ne couvre pas ici tous les détails techniques de ce principe, je me suis concentré sur son aspect essentiel.
Je suis impatient de vous faire découvrir d'autres principes de bon développement dans les prochains chapitres.

Read 5655 times Tagged under French
Sandra Thevenet

Sandra Thevenet

Of course, I am passionate about the web, and even more about Joomla! and especially its fabulous Community of people with whom it is so easy to share.
Some call me the CSS fanatic and I must confess, it is truly a passion for me.
From my little island, I try to contribute and participate to the Joomla! project.

----

Vous êtres francophone et vous souhaitez écrire ou traduire un article sur notre CMS préféré ? Contactez-moi par mail : sandra.thevenet@community.joomla.org