Le principe d’inversion de dépendance en pratique | C#

Le principe d’inversion de dépendance en pratique | C#

Introduction

Dans cet article, nous allons discuter du  principe d’inversion de dépendance en C#. Veuillez lire notre article précédent avant de passer à cet article où nous avons discuté du principe de séparation des interfaces en C#. La lettre D en SOLID signifie en anglais “Dependency“, représente le principe d’inversion de dépendance.

Qu’est-ce que le principe d’inversion de dépendance ?

Le principe est composé de deux règles :

  • Les modules de haut niveau ne doivent pas dépendre de modules de bas niveau. Les deux devraient dépendre d’abstractions.
  • Les abstractions ne doivent pas dépendre des détails. Les détails doivent dépendre des abstractions.

Ce principe vise principalement à réduire les dépendances entre les modules de code.

Inversion de dépendance vs injection de dépendance

Les gens confondent injection de dépendance et inversion de dépendance. D’une manière générale, l’injection de dépendances est un moyen d’obtenir une inversion de dépendances. Comme un outil pour réaliser le principe. Alors que l’inversion de dépendance indique simplement que vous devez dépendre des abstractions et que les modules de niveau supérieur ne doivent pas se soucier des dépendances des modules de niveau inférieur, l’injection de dépendance est un moyen d’y parvenir en étant capable d’injecter des dépendances.

Comment pouvons-nous atteindre le principe de l’inversion de dépendance ?

Vous pourriez obtenir l’inversion de dépendance en utilisant simplement le modèle “Factory” pour créer des modules de niveau inférieur en supprimant ainsi toutes les dépendances qu’ils ont et en leur faisant renvoyer des interfaces ainsi le module de niveau supérieur dépend sur les abstractions et ne sait même pas quelle est la classe concrète derrière l’interface.

Exemple d’implémentation

Imaginons que nous construisions un client de notifications. Nous voulons pouvoir envoyer des notifications par e-mail et SMS.

public class Email { public string ToAddress { get; set; } public string Subject { get; set; } public string Content { get; set; } public void SendEmail() { //Send email } } public class SMS { public string PhoneNumber { get; set; } public string Message { get; set; } public void SendSMS() { //Send sms } } public class Notification { private Email _email; private SMS _sms; public Notification() { _email = new Email(); _sms = new SMS(); } public void Send() { _email.SendEmail(); _sms.SendSMS(); } }
Code language: JavaScript (javascript)

La classe Notification, une classe de niveau supérieur, a une dépendance à la fois sur la classe Email et la classe SMS, qui sont des classes de niveau inférieur. En d’autres termes, la notification dépend de la mise en œuvre concrète de l’Email et du SMS, et non d’une abstraction de ladite implémentation. Puisque DIP veut que les classes de haut et de bas niveau dépendent d’abstractions, nous violons actuellement le principe d’inversion de dépendance.

Puisque les principes SOLID visent tous à réduire les dépendances, comment pouvons-nous factoriser ce code pour supprimer la dépendance entre Notification et Email / SMS ? Nous devons introduire une abstraction, sur laquelle la notification peut s’appuyer et que les e-mails et SMS peuvent implémenter. Appelons cela IMessage.

public interface IMessage { void SendMessage(); }
Code language: PHP (php)

Ensuite, Email et SMS peuvent implémenter l’interface IMessage :

public class Email : IMessage { public string ToAddress { get; set; } public string Subject { get; set; } public string Content { get; set; } public void SendMessage() { //Send email } } public class SMS : IMessage { public string PhoneNumber { get; set; } public string Message { get; set; } public void SendMessage() { //Send sms } }

Enfin, nous pouvons faire en sorte que Notification dépende de l’abstraction IMessage plutôt que de ses implémentations concrète.

public class Notification { private ICollection<IMessage> _messages; public Notification(ICollection<IMessage> messages) { this._messages = messages; } public void Send() { foreach(var message in _messages) { message.SendMessage(); } } }
Code language: PHP (php)

Nous avons permis aux classes (haut niveau et de bas niveau) de s’appuyer sur des abstractions. Donc confirmant ainsi le principe d’inversion de dépendance.

Conclusion

J’espère que cet article vous aide à comprendre le principe d’inversion de dépendance un peu plus en détails. Vos commentaires et critiques constructives sont toujours appréciés.

Partagez !

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *