mardi 13 novembre 2012

Le principe de responsabilité unique ( SRP ou Single Responsability Principle)


Durant mon expérience professionnelle j'ai eu se que j'appelle des "haaa moments", ces moments ou j'ai compris un truc qui à changé ma façon de travailler de manière positive.

Avant même de se lancer dans l'apprentissage de divers design pattern plus ou moins complexe, a mon sens, il est important d'avoir bien en tête 4 principes de base en programmation orienté objet:

-Le principe de responsabilité unique
-Le principe "ouvert/fermé"
-Le principe de substitution de Liskov
-Le principe d'inversion de dépendance

La découverte de ces 4 principes est un de ces "haaa moments".
D'un seul coup j'ai compris que la plupart des design pattern que je connaissais trouvais leur origine dans ces principes.
Et que s'il ne fallait retenir que 4 choses en programmation objets il valait mieux retenir ces 4 principes plutôt que 4 design pattern aussi puissants qu'ils puissent être.
Car appliquer ces 4 principes mène forcement à mettre en place volontairement ou non des design pattern.

Celui qui nous intéresse ici est le principe de responsabilité unique, qui est probablement le plus intuitif à comprendre.

"There should never be more than one reason for a class to change." — Robert Martin, SRP

Lorsqu'un développeur est confronté a un problème complexe il le découpe en plusieurs problèmes moins complexe jusqu’à résoudre le problème de départ.
Il va donc coder une solution pour chaque sous problème afin d'obtenir un code résolvant le problème complexe initial.
Chacun de ces morceaux de code à la responsabilité d'un sous problème.
Le principe de responsabilité unique nous incite à n'attribuer qu'une seule et unique responsabilité par classe.

Pourquoi ?

Pour répondre simplement, c'est parce que chaque responsabilité peut être a l'origine de modifications.
Chaque responsabilité est une raison de changements.
Une multitude de responsabilités dans une même classe aboutirait donc à une multitude de raisons de modifier cette classe.
Et plus une classe a de raisons d’être modifié moins elle est stable, la modification d'une responsabilité pourrait aboutir a un dysfonctionnement d'une autre responsabilité (effet dominos).

Prenons un exemple concret:

Un client vous demande une application simple de gestion de sa clientèle.
L'idée est de pouvoir afficher une liste détaillé de ses clients (nom,prénom,age, adresse) en mode console et de pouvoir sauvegarder dans son fichier client actuel d’éventuel nouveaux clients.
On aboutit à une modélisation assez simple de la classe Client :




Vous vous lancez dans le développement, sans trop de difficulté vous parvenez au resultat attendu par le client.
Fier de vous, vous présentez le résultat au client, qui entre temps à compris que nous n’étions plus dans les années 80, il souhaitait finalement donc une application web, et qu'il aimerait utiliser une base de données plutôt que son vieux fichier ASCII...

Une solution plus évolutive donnerai quelque chose dans ce gout la :



ClientDao s'occupe de sauvegarder un client
ClientIHM s'occupe d'afficher une liste de client
Client est la représentation d'un client.

De cette manière, la représentation d'un client est indépendante de l'affichage et indépendante de la sauvegarde d'un client.
Le jour ou le client voudra changer sa façon d'afficher la liste de ses client il suffira de modifier clientsIHM sans impacter les autres classes.
Cette indépendance est la clé de la ré-utilisabilité.
Certes le nombre de classe est multiplié mais il s'agit de petite classe robuste et réutilisable qui rende le code plus lisible.

En conclusion il est souhaitable d'oublier "l'objet magique" capable de tout faire, car il deviendra très rapidement difficile à maintenir voir carrément obsolète dés les premières évolutions !

Je tacherai de parler des autres principes que j'estime important dans de prochains billets.
En attendant pensez au SRP !!!


2 commentaires: