• 8 heures
  • Facile

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 19/03/2024

« S » pour le principe de responsabilité unique (« single responsibility »)

S pour le principe de responsabilité uniqueDans un orchestre, chaque musicien a un rôle distinct. Si, dans une symphonie, certaines notes doivent être jouées à la flûte, ce sont les flûtistes qui s’en chargent. S’il y a des notes à jouer au violoncelle, les flûtistes ne se jettent pas sur les violoncelles pour les jouer – ils ne s’occupent que de leur propre instrument, pendant que les violoncellistes s’occupent du leur !

Le fait que chaque musicien n’ait qu’une responsabilité unique facilite beaucoup l’écriture de musique pour un orchestre. De plus, cela facilite grandement la tâche au chef d’orchestre, qui doit résoudre les éventuels problèmes.

Les orchestres classiques savent très bien mettre en œuvre le principe de responsabilité unique – à savoir :

Une classe ou fonction ne doit faire qu’une chose – et la faire bien.

Autrement dit :

Une classe ou fonction ne doit avoir qu’une seule raison d’être modifiée.

Pourquoi utiliser le principe de responsabilité unique ?

Chaque personne qui utilise votre code doit pouvoir comprendre ce qu’il se passe. Le fait de réduire au minimum les responsabilités d’une classe aide à atteindre cet objectif.

Premièrement, le fait de trouver le code qui vous intéresse est facilité – une idée correspond à un emplacement qui l’implémente. Dans notre jeu de cartes, nous savons que tout ce qui est associé à une carte à jouer se trouvera dans la classe  Card  (Carte)  .

Deuxièmement, les tests unitaires sont beaucoup plus faciles à écrire. Bien que nous n’en ayons pas écrit pour notre application, les tests pour  Card  n’auraient besoin de valider que les quelques éléments dont  Card  est responsable (rang, couleur, et si la carte est face vers le haut).

Et enfin, la création d’un nom de classe ou de fonction est facile (car ce qu’elle est censée faire est clair).

Résumons notre approche :

  • Pour chaque responsabilité, assurez-vous qu’elle est placée dans la bonne classe.

  • Si une classe fait trop de choses différentes, créez de nouvelles classes pour séparer les responsabilités.

Comment appliquer le principe de responsabilité unique à notre code ?

Ce principe est facile à enfreindre. Vous pouvez l’enfreindre notamment lorsque vous devez ajouter de nouvelles fonctionnalités au système. Chaque partie de fonctionnalité doit aller quelque part, non ? Il semble souvent sensé de placer de nouvelles choses dans une classe existante. Mais alors, la classe se retrouve avec plus d’une chose à faire.

Observons notre jeu de cartes. L’une des premières classes que nous avons implémentées est  Card  . Elle connaît le rang et la couleur d’une carte, si elle est face vers le haut, et si elle est meilleure que les autres cartes dans le contexte du jeu.

D'ailleurs, il existe une situation courante dans laquelle nous devrons modifier continuellement cette classe. Vous voyez laquelle ? 🤔

Eh oui – chaque fois que nous voudrons utiliser ces cartes pour un jeu différent avec des règles différentes (par exemple, si les plus petites cartes ont plus de valeur), alors nous devrons modifier ou remplacer la classe  Card  !  Card  ne doit pas être responsable de l’implémentation de la logique du jeu, car elle doit alors être modifiée en parallèle dès que la logique du jeu change.

Dans la vraie vie, vous n’avez pas besoin de jeux de cartes différents pour chaque jeu auquel vous jouez. La même règle doit s’appliquer à notre application.

Alors, si ce n’est pas notre classe  Card  , quelle proposition parmi les suivantes pourrait implémenter l’évaluation du vainqueur sans enfreindre le principe de responsabilité unique ?

  • Controller  (Contrôleur).

  • View  (Vue).

  • Player  (Joueur).

Essayez par vous-même avec ce code.

Puis, regardez la solution dans la vidéo ci-dessous :

Voici le lien vers le code.

La classe  Player  ne doit pas avoir à changer à chaque fois que nous jouons à un nouveau jeu, donc l’évaluation du vainqueur n’y a pas sa place. Je ne devrais pas avoir à remplacer mes amis lorsque je décide de jouer à un nouveau jeu…

La classe  View  ne doit pas posséder les responsabilités non liées de présenter le jeu et de décider qui gagne. Je ne devrais pas avoir à acheter un nouvel écran à chaque fois que je veux regarder un jeu différent…

Il nous reste alors la classe  Controller  ! Elle est responsable de l’exécution du jeu, indépendamment de qui est en train de jouer ou du mode d’affichage du jeu. On ne doit la modifier que pour une raison : si les règles du jeu changent.

En résumé

  • La responsabilité unique signifie que chaque classe ou fonction ne doit faire qu’une chose, c’est-à-dire qu’il ne doit y avoir qu’une seule raison de la modifier.

  • C’est un principe facile à enfreindre quand vous ajoutez de nouvelles fonctionnalités au système. Lorsque vous ajoutez une nouvelle fonctionnalité, posez-vous ces questions :

    ○      Quels sont les changements à venir qui pourraient impacter cette classe ?

    ○      Qu’est-ce qui pourrait donner à la classe plus d’une raison d’être modifiée ?

  • N’oubliez pas que, si une classe imite un concept de la vraie vie, elle doit implémenter uniquement la responsabilité unique qui correspond à ce concept du monde réel.

Regardons comment ajouter plus de capacités à notre système, mais sans modifier ce que nous avons écrit jusqu’ici, en appliquant le principe ouvert/fermé.

Exemple de certificat de réussite
Exemple de certificat de réussite