DRY, qui correspond à Don’t Repeat Repeat Yourself, est un micro-principe utilisé en développement logiciel et qui vise à éviter la répétition d'éléments clé au minimum. Une définition formelle est :
[e]very piece of knowledge must have a single, unambiguous, authoritative representation within a system.
Bien qu'il s'agisse d'un principe très simple — en principe — DRY est parfois mal interprété comme la nécessité de ne jamais répéter deux fois la même chose au sein d'un projet. Ce qui est peu pratique et habituellement contre-productif, et peut amener à des abstractions forcées, over-thought and -engineered code, and unusual dependencies.
La clé n'est pas d'éviter toutes les répétitions, mais de normaliser et d'abstract meaningful repetition. S'il arrive que deux choses partagent la même déclaration coincidentally, nous n'avons pas besoin d'appliquer DRY; c'est répétition est purement circonstancielle et ne doit pas être partagée ou abstraite. Par exemple :
.btn { display: inline-block; padding: 1em 2em; font-weight: bold; } [...] .page-title { font-size: 3rem; line-height: 1.4; font-weight: bold; } [...] .user-profile__title { font-size: 1.2rem; line-height: 1.5; font-weight: bold; }
Du code ci-dessus, nous pouvons raisonnablement dire que la déclaration font-weight: bold; apparaît trois fois de manière purement coincidentally. Créer une abstraction, mixin ou directive @extend pour prendre en charge cette répétition serait de trop, et lierait trois bases de règles pour des raisons purement circonstancielles.
Cependant, imaginons que nous utilision une font web qui requiert de déclarer font-weight: bold; chaque fois que font-family l'est :
.btn { display: inline-block; padding: 1em 2em; font-family: "My Web Font", sans-serif; font-weight: bold; } [...] .page-title { font-size: 3rem; line-height: 1.4; font-family: "My Web Font", sans-serif; font-weight: bold; } [...] .user-profile__title { font-size: 1.2rem; line-height: 1.5; font-family: "My Web Font", sans-serif; font-weight: bold; }
Ici nous répétons a more meaningful snippet of CSS; ces deux déclaration devraient toujours être déclarées ensemnle. Dans ce cas, on utiliseras probablement DRY dans notre CSS.
Je recommanderais d'utiliser une mixin plutôt qu'un @extend ici car, bien que les deux déclarations soir regroupées thématiquement, les bases de règles sont toujours des entités séparées et non relatives : utiliser @extend grouperais physiquement ces bases de règles dans notre CSS, reliant ce qui ne l'est pas.
Notre mixin:
@mixin my-web-font() { font-family: "My Web Font", sans-serif; font-weight: bold; } .btn { display: inline-block; padding: 1em 2em; @include my-web-font(); } [...] .page-title { font-size: 3rem; line-height: 1.4; @include my-web-font(); } [...] .user-profile__title { font-size: 1.2rem; line-height: 1.5; @include my-web-font(); }
Ces deux déclarations n'existent maintenant plus qu'une fois, signifiant que nous ne répétons plus. Si jamais nous changons de police, ou que nous passons à une version font-weight: normal; nous n'aurons plus besoin de faire ce changeemnt qu'à un seul endroit.
En bref, n'utiliser DRY que pour du code lié réellement et thématiquement. Ne l'utilisez pas pour une répétition purement coincidente : la duplication est meilleurs qu'une mauvaise abstraction.