Les principes S.O.L.I.D

Le but et le résumé des points


Les principes S.O.L.I.D sont 5 principes importants pour nous permettre à nous développeur d'écrire du bon code ces derniers sont constitué des 5 éléments suivant et peuvent être résumé de la façon suivante :

  • Single Responsibility Principle où SRP, ce principe s'applique sur les classes et nous dit qu'une classe ne doit avoir qu’une seule responsabilité.
  • Open / Closed Principle où OCP, ce principe s'applique lui aussi sur une classe et nous informe que notre classe doit être ouverte à l'extension (possibilité d'héritage...) mais fermé à la modification (attributs en privés...).
  • Liskov Subtitution Principle où LSP, ce principe s'applique sur des objets et permet de remplacer un objet par une instance d'un sous-type de l'objet à remplacer sans "casser" notre système.
  • Interface Segregation Principle où ISP, ce principe nous dis une grande interface générique est plus désavantageuse que plusieurs interfaces spécifiques.
  • Dependancy Inversion Principle où DIP, ce principe nous dis que pour avoir un meilleur code, il faut dépendre d'abstraction qui seront spécifiés et non directement de ces spécifications.
  • Comme nous l'avons vu dans le résumé, le principe SRP consiste à ce qu'une classe et une seul responsabilité. Nous allons donc voir cela à l'aide d'un exemple (ci-dessous). 

    SRP

    Cette image nous présente la modélisation d'un système de forum. Je vous laisse prendre connaissance du diagramme de classe avant de continuer (vous devez normalement savoir le faire depuis le temps 😉 ). Pour vous expliquer le concept de SRP, nous allons prendre l'exemple d'un utilisateur qui créer un nouveau message sur un forum.

    L'utilisateur va donc envoyer son message sur un forum et un système non représenté ici va recevoir ce dernier, nous l’appellerons le contrôleur. À ce moment-là, le contrôleur va demander au gestionnaire de forum de vérifier que le forum ou l'utilisateur souhaite envoyer son message existe en recherchant le forum par son nom. Si le forum existe il le retourne sinon notre fonction renvoie null.

    Maintenant, nous pourrions nous dire que le gestionnaire de forum va demander au forum qu'il vient de trouver de trouver le canal ou le message doit être posté puis poster ce dernier mais si nous mettons cela en place, nous ne respecterons pas le SRP. Pourquoi ? Car notre forum aurait la responsabilité des forums ainsi que de la création de message.

    Il faut donc retourner le forum précédemment trouvé à notre contrôleur qui dans notre cas est celui qui à cette responsabilité.

  • Comme nous l'avons vu dans le résumé, le principe OCP consiste à être fermé à la modification de nos classes mais être ouvert à l'héritage.

    Pour ce qui est du côté fermé de nos classes, il faut être attentif à la protection que l'on met sur un attribut ainsi que sur nos méthodes. Pour bien fermer ses classes, il est conseiller en général d'avoir les attributs en privé et de pouvoir l'utiliser par des accesseurs. Il est aussi possible de les mettre en protected pour que les attributs soient protégés de l'extérieur mais qu'il soit directement accessible par la classe étendant notre classe.

    Pour ce qui est du l'ouverture à l'héritage, observons le diagramme ci-contre.OCP

    Dans ce diagramme on peut voir que la classe Cheap n'a pas directement comme attribut la classe Flight, Room ou Car mais une interface PayingItem qui est implémenté par les différentes classes. Dans notre cas, la classe Cheap possède un attribut "low" de type PayingItem. Cela permet à notre classe Cheap d'avoir des objets de type Flight, Room ou Car.

    Nous avons par cette méthode ouvert notre classe à l'héritage.

  • Comme nous l'avons vu dans le résumé, le principe LSP consiste à ce qu'une instance d'une sous-classe qui remplace sa sur-classe ne casse pas tout le système. 


    Nous allons donc voir cela à l'aide d'un exemple (ci-contre). LSP Dans cette exemple (en imaginant que la classe State n'est pas une classe abstraite et qu'elle défini la méthode getProtection()), on observeve que nos 3 classes Dead, Living et Low surcharge la méthode getProtection(). Émettons l'hypothèse que la méthode de la classe Dead  retourne une erreur car nous ne pouvons pas nous protéger lorsque nous sommes mort. Dans ce cas la, nous ne respectons pas le principe LSP car remplacer State par Dead "casserait" le système.

  • Comme nous l'avons vu dans le résumé, le principe ISP consiste à ne pas utiliser une interface trop générique mais à spécifier ces interfaces et à les implémenter. 
    Ce principe n'étant pas très complexe, voici en premier le mauvaise exemple.
    InterfaceGénérale

    Et voici l'exemple d'interface spécifié qui répond au principe ISP.
    InterfaceSpécifique

  • Comme nous l'avons vu dans le résumé, le principe DIP consiste à dépendre au minimum de classe concrète mais plus de classe abstraite ou des interfaces.

    Comme cela est inclus dans le prinicipe SRP, je vous remet le principe ci-dessous. Pour ce qui est du l'ouverture à l'héritage, observons le diagramme ci-contre.OCP

    Dans ce diagramme on peut voir que la classe Cheap n'a pas directement comme attribut la classe Flight, Room ou Car mais une interface PayingItem qui est implémenté par les différentes classes. Dans notre cas, la classe Cheap possède un attribut "low" de type PayingItem. Cela permet à notre classe Cheap d'avoir des objets de type Flight, Room ou Car.

    Nous avons par cette méthode ouvert notre classe à l'héritage.

S'évaluer


Quiz

Que signifie le I de S.O.L.I.D ?

Combien de responsabilité conseille d'avoir la méthode SRP

Quelles sont les 2 principes d'OCP ?

LSP consiste à :

DIP consiste à :

ISP consiste à :



Votre note :