Quand utiliser des interfaces?
J’ai récemment découvert le concept de Interface-based programming (également appelé Interface-based architecture). Il s’agit d’un modèle d’architecture reposant sur des interfaces plutôt que des implémentations. J’ai notamment eu l’occasion d’expérimenter cette technique de manière dogmatique où toute classe d’un projet (service, DTO, value object, entité de base de données, modèle métier…) devait être liée à une interface. L’objectif d’une telle architecture est de concevoir une application par “contrat” et d’avoir du code entièrement découplé de toute implémentation.
Malheureusement, avoir une approche dogmatique qui pousse à appliquer un concept de manière systématique sans se poser de questions sur le contexte dans lequel il est utilisé peut annuler les bénéfices qu’il serait possible d’en tirer. Ce fut l’occasion pour moi de me poser la question: quand est-il judicieux d’utiliser des interfaces de classe?
J’ai donc beaucoup réfléchi à cette question et fait de nombreuses recherches sur le sujet. Je suis finalement tombé sur un article de Mathias NOBACK “When to add an interface to a class” qui résume tellement bien mon point de vue sur le sujet que je vous recommande vivement de le lire. A défaut vous trouverez les principales lignes directrices ci-dessous:
- Une classe définit de manière implicite un contrat d’utilisation au travers de ces méthodes publiques. Créer une interface peut-être utile si ces dernières ne devraient pas être accessibles.
- Lorsque du code interagit avec le système de fichier, du réseau ou n’importe quel système tiers, la mise en place d’une interface est essentielle pour se découpler de l’implémentation et faciliter l’écriture de tests.
- De la même manière que le point précédent, si votre code utilise du code que vous ne maintenez pas vous-même, mettre en place une interface vous permettra de changer simplement l’implémentation que vous avez utilisée.
- Si vous travaillez sur un système informatique ou des développeurs tiers peuvent surcharger ou remplacer le fonctionnement par défaut, une interface permettra de définir le contrat attendu pour fonctionner.