SOLID – Interface Segregation

On touche presque au but. La ségrégation des interfaces, le 4ème principe SOLID. Même s’ils sont tous importants, j’aime penser qu’il est un peu la pierre angulaire du SOLID. Ici, nous allons faire référence directement aux interfaces (exemple pour le PHP) de la programmation orientée objet. Prenons le temps d’un rappel succinct sur ce qu’est une interface en OOP.

Qu’est-ce qu’une interface ?

Une interface est un mot-clé dans la programmation objet qui va nous permettre d’écrire une liste de méthodes. On peut le voir comme une liste de choses à faire, un contrat a respecter pour tout objet souhaitant implémenter cette interface. A partir de ce moment-là, c’est un peu comme si vous étiez en train de créer votre propre “Type” et de fait, l’objet qui implémente une interface est aussi un de ces “types”.

Il faut donc comprendre que lorsqu’un développeur souhaitera utiliser une interface, cela lui oblige l’implémentation des méthodes décrites mais ensuite, cela pourra aider l’application à comprendre le type d’information qu’il est en train de recevoir et quel traitement il va pouvoir effectuer dessus.

Qu’en est-il du principe ?

Il peut arriver régulièrement que par “flemmardise” ou autres, on souhaite se mettre a écrire des interfaces, juste “histoire d’avoir” une interface ; parce qu’on vous a dit que c’était cool. Vous commencez donc à développer votre application et, pour notre exemple, nous allons imaginer devoir gérer des utilisateurs. On va avoir envie de leur envoyer des emails, des SMS, des courriers,… tout ce que l’on aime 🙂 Mais surtout, on ne va pas gérer que des utilisateurs… on décide pour une raison quelconque, de gérer plusieurs types d’utilisateurs et on va en faire plusieurs objets.

Et là, c’est déjà le drame. Quelques lignes de code et c’est déjà l’apocalypse. Vous ne respectez pas le principe de ségrégation des interfaces. Qu’est-ce qu’il en est ?

L’idée est de séparer les interfaces pour qu’elle n’est qu’une utilité restreinte. En réalité, on pourrait presque l’apparenter au principe de la responsabilité unique. Ici, bien qu’on sépare 2 entités utilisateurs pour les besoins de notre application imaginaire, il faut bien comprendre que la logique métier de notre application nous montre bien qu’il y a un problème avec l’objet “LeadUser”. On n’a pas connaissance de son téléphone ni de son adresse. Il n’est contactable que par email. Pour éviter cela, vous devez donc “atomiser” vos interfaces et les différencier :

Vous pensez qu’un type d’utilisateur doit avoir nécessairement besoin de ces 3 informations ? Très bien, faites une interface qui étend tout ce dont vous avez besoin :

Ca paraît inutile d’écrire cela ? Pourtant non. A la lecture du code et grâce au nommage des fichiers, on est capable de comprendre ce qu’il en est au niveau de l’architecture et de la conception de l’application. Maintenant, quelle utilité ? Afin de ne pas aller trop et déborder sur le prochain principe SOLID, vous allez pouvoir l’utiliser au sein d’objets que j’appelle des “services” qui vont chercher à utiliser ces informations. Typiquement, on a besoin de ses informations pour envoyer… des emails par exemple! Faisons le service approprié 🙂

Vous ne voyez toujours pas l’intérêt ? Le service d’envoi d’email demande nécessairement un objet en paramètre qui implémente l’interface “EmailInterface”. De fait, nous avons la certitude de pouvoir utiliser la méthode “getEmail” car si nous n’envoyons pas un objet avec la bonne implémentation, votre application va planter littéralement, vous savez, la fameuse “Fatal error” 🙂 Alors que si vous aviez juste mis en paramètre “email” en tant que simple chaîne de caractères, vous n’avez aucun contrat qui vous certifie la provenance et le fait que vous allez utiliser un email. Et c’est donc plus robuste, plus maintenable et plus testable !