Skip to content

Articles

L'injection de dépendances peut-elle faire de moi un meilleur programmeur Python ?

16 février 2025 • 4 min de lecture

L'injection de dépendances peut-elle faire de moi un meilleur programmeur Python ?

L’injection de dépendances est un pilier dans les langages statiques, mais est-ce que cela a du sens de l’utiliser en Python ? Est-ce que cela fera de moi un meilleur programmeur Python ?

Et, attendez, qu’est-ce que l’injection de dépendances, déjà ?

D’abord, répondons à la question : Qu’est-ce que l’injection de dépendances (DI) ?

L’injection de dépendances est un motif qui, lorsqu’il est utilisé, déplace la construction d’un objet à l’extérieur de la classe. Au lieu de cela, la classe prend une dépendance sur une abstraction.

Dans les langages statiques comme C# et Java, l’injection de dépendances est largement utilisée pour réduire le couplage et faciliter les tests. En fait, vous trouverez des frameworks d’injection de dépendances dont le seul but est de maintenir les dépendances et leurs relations entre elles.

L’injection de dépendances sert deux objectifs principaux :

Premièrement, elle réduit la complexité en prenant une dépendance sur une abstraction.

Deuxièmement, dépendre d’une abstraction permet à différentes implémentations, y compris des mocks pour les tests, d’être passées dans la classe ou la fonction.

Laissez-moi démontrer avec du code :

# Avant 
class User:
    def __init__(self):
        self.database = SqlServerDatabase()

    def get_details(self, user_id: int):
        self.database.get_user_details(user_id)

# Après  
class User:
    def __init__(self, database: Database):
        self.database = database

    def get_details(self, user_id: int):
        self.database.get_user_details(user_id)

C’est l’injection de dépendances dans sa forme la plus simple. Bien que le concept soit simple, sa puissance réside dans la possibilité de créer des conceptions flexibles.

Dans l’exemple Avant, la classe User est étroitement couplée à la classe SqlServerDatabase. Si nous voulons tester la classe User, nous devons créer une nouvelle instance de SqlServerDatabase.

Dans l’exemple Après, la classe User est faiblement couplée à l’abstraction Database. Nous pouvons passer une implémentation différente de l’abstraction Database à la classe User.

Laissez-moi démontrer cette flexibilité avec un exemple pratique qui montre comment nous pouvons basculer entre différentes implémentations de base de données :

date_string = "2023-10-01"  # Exemple de chaîne de date
date_format = "%Y-%m-%d"    # Format de chaîne d'entrée
birthday = datetime.strptime(date_string, date_format) 
turn_of_the_century = datetime.strptime('2000-01-01', date_format)

database = PostgresDatabase("")

if birthday < turn_of_the_century:
    database = SqlServerDatabase("")

user = User(database=database)
user.get_details(user_id=1)

À la ligne 6 (birthday < turn_of_the_century), l’injection de dépendances nous permet d’échanger facilement les implémentations en fonction de différentes conditions. Bien que cette flexibilité soit précieuse pour le code de production, l’une des utilisations les plus courantes de l’injection de dépendances, en particulier dans les langages statiques, est dans les tests.

Voici un exemple :

class UserTests(unittest.TestCase):
    def test_is_authenticated(self):
        database = MockDatabase('connection_string')
        
        is_authenticated = User(database).is_authenticated('user', 'pass')

        self.assertTrue(is_authenticated)

C’est un exemple simple utilisant une classe MockDatabase. En Python, nous pourrions également utiliser la classe Mock intégrée pour obtenir le même résultat.

Fait intéressant, l’injection de dépendances n’était pas largement utilisée dans les projets Python sur lesquels j’ai travaillé. Venant d’un background de langages statiques, j’ai été surpris— et cela semblait contre-intuitif.

Cependant, il y a une raison à cette adoption limitée. La fonctionnalité de patch intégrée de Python fournit déjà d’excellentes capacités de test, éliminant l’un des principaux avantages de l’injection de dépendances. Bien que l’injection de dépendances puisse encore aider à réduire la complexité, Python a d’autres approches pour atteindre le même objectif.

Je ne dis pas que l’injection de dépendances ne devrait pas être utilisée en Python. Bien au contraire, comme tous les outils et motifs, il y a un lieu et un moment pour les utiliser. Et l’injection de dépendances n’est qu’un autre outil dans votre boîte à outils qui améliorera la qualité de votre code.

Je pense que l’injection de dépendances augmenterait généralement la qualité du code dans la plupart des projets Python.

Si vous êtes intéressé par l’exploration plus approfondie de l’injection de dépendances, je recommande de consulter deux frameworks Python populaires :

  • Injector (github.com/python-injector/injector)
  • Dependency Injector (python-dependency-injector.ets-labs.org)

Auteur : Chuck Conway se spécialise dans l’ingénierie logicielle et l’IA générative. Connectez-vous avec lui sur les réseaux sociaux : X (@chuckconway) ou visitez-le sur YouTube.

↑ Retour en haut

Vous pourriez aussi aimer