Code Python faiblement couplé avec injection de dépendance
Le logiciel doit être flexible afin de répondre au changement. L'injection de dépendances est une technique de gestion des dépendances entre composants logiciels. Il s'agit d'un modèle de conception qui utilise l'inversion de contrôle pour fournir la possibilité d'échanger des composants à des fins de test ou à d'autres fins sans modifier aucune autre partie du système.
L'idée principale derrière l'injection de dépendances est de transférer la responsabilité de fournir des services à partir de fonctions constructeur ou de méthodes d'instanciation directe sur d'autres objets. En d'autres termes, un objet reçoit ses dépendances au lieu de les créer. De cette façon, si nous voulons ajouter de nouvelles fonctionnalités, nous n'avons pas besoin de modifier le code existant, mais plutôt de lui transmettre de nouvelles dépendances.
Créer des abstractions avec des interfaces
Il y a trois étapes dans l'écriture de code Python faiblement couplé avec injection de dépendances. La première étape consiste à identifier les dépendances dont le code a besoin, la deuxième étape consiste à créer des interfaces pour chaque dépendance et la troisième étape consiste à les transmettre à l'objet dépendant via ses paramètres de constructeur ou de méthode.
Récemment, j'ai implémenté une fonctionnalité qui nécessitait un encodeur et un décodeur d'octets pour manipuler les données de l'entreprise ( j'ai simplifié son implémentation à des fins de lisibilité ). J'ai résumé leurs responsabilités aux interfaces. Python n'a pas de mot-clé d'interface comme Golang, mais vous pouvez répliquer la fonctionnalité d'interface avec la bibliothèque ABC .
En se concentrant sur l' IPacketEncoderinterface, une classe d'encodeur concrète doit l'implémenter. Les exigences commerciales initiales exigeaient que tous les types soient encodés et que les chaînes soient remplies avec leur longueur. Heureusement, Python fournit la bibliothèque de structures pour effectuer la majeure partie du travail acharné.
Implémentation de l'injection de dépendance
La encode_namefonction est une implémentation simple pour créer une charge utile codée avec le nom spécifié. Il prend un IPacketEncoderobjet et une chaîne comme paramètres.
Les deux détails d'implémentation clés utilisent l' IPacketEncoderinterface au lieu de la PaddedPacketEncoderclasse concrète et encoderconstituent un argument plutôt que d'être initialisés à l'intérieur de la fonction. C'est l'injection de dépendance. Parce IPacketEncoderqu'il est introduit, il peut être facilement étendu, changé ou muni d'un embout , ce qui maintient le système lâchement couplé.
Quelques semaines plus tard, il y avait une nouvelle exigence pour qu'un encodeur gère les encodages à terminaison nulle. Heureusement, en raison de l'implémentation existante, il peut être facilement mis en œuvre.
NullTerminatedPacketEncoderajoute essentiellement NULL_BYTEaprès chaque chaîne encodée. Pour en revenir à la encode_namefonction, une instance de NullTerminatedPacketEncoderest un argument d'encodeur valide car NullTerminatedPacketEncoderimplémente l' IPacketEncoderinterface de la même manière que PaddedPacketEncoder.
Si l'injection de dépendance n'était pas utilisée ici, cela pourrait entraîner un code étroitement couplé et difficile à modifier, par exemple :
Si un nouveau codeur est nécessaire, la encode_namefonction devra être changée presque entièrement ainsi que ses tests, ce qui allongera les délais de livraison. Pire encore, cela pourrait entraîner des effets secondaires cachés, surtout si le développeur d'origine n'est plus disponible.
Pour conclure, je vais donner un exemple moins simpliste utilisant cette technique. SocketServiceest chargé de décoder un code d'opération, d'appeler son gestionnaire approprié et de renvoyer son résultat. Tous ses types d'arguments sont des abstractions d'interface, y compris son constructeur. La CLI est chargée de déterminer quel encodeur utiliser, c'est-à-dire NullTerminated ou Padded, et de transmettre son instance à la SocketServiceclasse.
Au fur et à mesure que les projets continuent de croître, il est recommandé d'utiliser un framework d'injection de dépendances pour "injecter" ces dépendances automatiquement, comme Dependency Injector .
Espérons que cela montre comment écrire du code Python faiblement couplé avec injection de dépendance. De nombreux développeurs Python n'aiment pas l'injection de dépendances car ils estiment que ce n'est pas "pythonique", mais je dirais que ses avantages ne peuvent être discrédités, surtout lorsqu'ils sont présents dans tant d'autres langages de programmation.
Merci d'avoir lu . Si vous souhaitez me contacter, vous pouvez me trouver sur Linkedin ou Github .
![Qu'est-ce qu'une liste liée, de toute façon? [Partie 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































