7 min de lecture
52 vues

SRP : SINGLE RESPONSIBILITY PRINCIPLE (Responsabilité unique)

SRP : SINGLE RESPONSIBILITY PRINCIPLE (Responsabilité unique)

Introduction à la série SOLID

SOLID, c’est un ensemble de principes de conception orientée objet qui définissent les bases d’une architecture logicielle robuste, flexible, compréhensible et facilement maintenable.

Ces principes aident à produire des systèmes avec moins de bugs, moins de régressions, plus faciles à faire évoluer, et surtout plus maîtrisés dans leur fonctionnement.

🔗 Source : Wikipédia - SOLID (informatique)

📝 Note : Les principes défendus par l’acronyme SOLID apparaissent pour la première fois dans l’article “Design Principles and Design Patterns” publié en 2000 par Robert C. Martin (aussi appelé Uncle Bob).

Le terme SOLID, quant à lui, a été introduit plus tard par Michael Feathers.


Pourquoi une série sur les principes SOLID ?

Dans cette série, on va plonger en détail dans chacun des cinq principes avec des exemples simples, concrets et accessibles.

L’idée, c’est de démystifier ces concepts parfois intimidants et de t’aider à :

  • mieux comprendre les bases de l’architecture logicielle,

  • impressionner tes collègues ou camarades d’école 😉,

  • écrire du code plus propre, plus durable et plus intelligemment structuré.

🛠️ Note : Il existe plusieurs approches et paradigmes en matière de conception.

Apprendre les principes SOLID ne signifie pas que tu devras les appliquer systématiquement à tous tes projets.

Mais cela te donne des outils puissants à mobiliser intelligemment selon le contexte, les contraintes et les objectifs du projet.

SRP

Le premier principe n'est autre que la responsabilité unique — en anglais Single Responsibility Principle, abrégé SRP.

De manière générale, ce principe se divise en deux composantes à bien comprendre. D'abord, sa composante "unique", qui est assez simple : comme son nom l’indique, il n’y a pas de piège, cela veut juste dire qu’il ne doit exister qu’une seule responsabilité pour notre entité dans le contexte global de notre projet. Ensuite, la composante "responsabilité", un peu plus complexe à cerner. En effet, on dira qu’elle représente une raison de changer, ou plus concrètement une fonction, un rôle, ou une mission que remplit une entité (classe).

L’objectif de ce principe est donc de restreindre au maximum cette raison pour la rendre le moins étendue possible et unique dans le contexte de notre projet.

On dira donc que ce principe soutient l’idée que chaque entité doit avoir une seule raison de changer, donc faire une seule chose, et la faire bien — ou, pour être un peu plus strict, n’avoir qu’une seule action cohérente.

Ce principe vise donc à résoudre plusieurs problèmes, notamment :

  • le débogage : si toutes les classes ont une responsabilité unique, alors les bugs se repèrent vite car les traces d'erreur (tracebacks) sont très courtes ;

  • la facilité de compréhension : étant donné que chaque classe ne s’occupe que d’opérations du même type, il est facile de comprendre son rôle ;

  • une meilleure testabilité (oui, je me permets le terme 😄) : une classe avec un seul comportement est facilement isolable lors des tests ;

  • une facilité de modification : si je ne contrôle qu’un seul morceau du système, alors mes changements ne risquent pas d’impacter l’ensemble du système — ce qui les rend plus rapides et plus simples.

Bon, ça fait déjà beaucoup de texte, je sais, moi aussi je suis fatigué 😅. Prenons ensemble un petit exemple concret (dans le cadre du développement logiciel). Imaginons qu’on veuille mettre en place un système de gestion d’imprimante dans un "chop" pas loin de chez vous — oui, celui du coin de la rue ou au marché du quartier oui oui tu sais de quoi je parle.

La plupart du temps, notre code ressemblera à ceci (je dis bien pour ceux qui ne connaissent pas encore notre ami SRP... pour les autres, y en a même qui auront tout mis dans un seul fichier pour gagner du temps hein je vous ai attrapé !) :

Une classe Printer qui englobe toutes les opérations qu’on sait lier à une imprimante :

 
public class Printer {
 
public void print(Document doc) {
 
// Imprime le document
 
}
 
 
public void scan(Document doc) {
 
// Scanne le document
 
}
 
public void sendFax(String number, Document doc) {
 
// Envoie le fax
 
}
 
public void logActivity(String message) {
 
// Enregistre une trace dans un fichier log
 
}
 
}

Je sais,oui je sais vous vous dites :

Mais où est le souci dans cette classe ? Elle fait tout ce qu'une imprimante doit faire !

Justement… elle fait TROP ! Je vais vous le dire. En fait, cette classe a plusieurs responsabilités (vous vous imaginiez une réponse lunaire ? non, on reste simple), notamment :

  • l'impression (print)

  • la numérisation (scan)

  • le fax (sendFax)

  • la journalisation (logActivity)

Et chacune de ces actions peut évoluer indépendamment en influençant les autres. Quelques exemples :

  • Si le système de fax change (par exemple, on passe par une API au lieu d’un modem, ou on veut gérer plusieurs moyens d’envoi), seule sendFax devrait être modifiée.

  • Si la politique de journalisation change (ex. : on stocke les logs dans un fichier JSON ou dans une base de données), seule logActivity est concernée.

  • Si on change le module d’impression pour un pilote spécifique, seule print devrait bouger.

  • Imaginez qu’on passe à des machines dernier cri qui ne supportent plus les anciennes méthodes, mais qu’on veuille quand même garder l’ancien matériel : là, vous voyez bien que le tout-en-un ne passe plus 😅

Bref, ce code devient difficile à maintenir, à tester, et fragile face aux changements (par exemple, un bug dans logActivity peut impacter l’impression — ce qui n’a aucun sens).


Oui, on y est : le moment que vous attendiez tous 😄 — la solution !

Et rassurez-vous, ce n’est pas aussi technique que ce que vous pensiez. En fait, vous l’avez sûrement deviné : il y a quatre comportements distincts (je ne vais pas vous les reciter pour ceux qui compte sur moi, faut bien un peu tester votre mémoire vous ne m'envodrez pas — sinon remontez juste au-dessus 👀).

Donc pour mieux modéliser notre système, il faut quatre classes distinctes, comme ceci :

 
// Classe dédiée à l'impression
 
public class Printer {
public void print(Document doc) {
 
// Logic for printing the document
 
}
}
 
// Classe dédiée à la numérisation
 
public class Scanner {
 
public void scan(Document doc) {
 
// Logic for scanning the document
 
}
 
}
 
// Classe dédiée à l'envoi de fax
 
public class FaxMachine {
 
public void sendFax(String number, Document doc) {
 
// Logic for sending a fax
 
}
 
}
 
// Classe dédiée à la journalisation
 
public class Logger {
 
public void logActivity(String message) {
 
// Logic for logging actions
 
}
 
}

Cette solution apporte plein d’avantages : chaque classe est responsable de son comportement et de ses évolutions, donc plus facile à tester, à maintenir, à comprendre, à faire évoluer, etc.

Petit exemple d’utilisation de notre nouvelle architecture :

 
Printer printer = new Printer();
 
Scanner scanner = new Scanner();
 
FaxMachine faxMachine = new FaxMachine();
 
Logger logger = new Logger();
 
 
 
Document doc = new Document("SRP_Article.pdf");
 
 
 
printer.print(doc);
 
scanner.scan(doc);
 
faxMachine.sendFax("+123456789", doc);
 
logger.logActivity("Document traité : SRP_Article.pdf");

🧩 Conclusion

Le Single Responsibility Principle est bien plus qu’une règle théorique : c’est un pilier fondamental pour écrire du code propre, modulaire et maintenable.

En veillant à ce qu’une classe n’ait qu’un seul motif de changement, on évite bien des galères.

Une bonne pratique : se poser les bonnes questions.

  • Est-ce que ma classe fait plus d’une chose ( a plus d’une mission ) ?

  • Est-ce que je peux diviser ses rôles ( actions de ma classe ) en classes spécialisées ?

  • Si une règle métier change demain, qu’est-ce que ça va casser ?

Adopter le SRP, c’est faire un pas vers un code plus solide, plus simple, et surtout plus durable.

Merci d’avoir pris le temps de lire jusqu’ici 🙏

Si t’as des questions ou des incompréhensions, écris-moi !

Et si t’as aimé cet article, reste connecté pour la suite avec les 4 autres principes SOLID. À la prochaine ! 💻🔥