Avancé
🧠 Fondamentaux
30 XP
0 personnes ont réussi
DIP : Inversion des dépendances
Le dernier principe SOLID est l'inversion des dependances (DIP) : les modules de haut niveau ne doivent pas dependre des modules de bas niveau. Les deux doivent dependre d'abstractions.
En pratique, ca veut dire : au lieu d'écrire du code qui utilise directement une classe concrete (comme NotificateurEmail), tu ecris du code qui utilise une abstraction (comme Notificateur). Ensuite, tu injectes l'implémentation concrete au moment de la création.
C'est comme une prise electrique : ton appareil (haut niveau) ne depend pas du type exact de cable (bas niveau). Il depend de l'interface prise (abstraction). Tu peux brancher n'importe quel cable compatible.
# MAUVAIS : depend directement de Email class ServiceCommande: def __init__(self): self.notif = NotificateurEmail() # dependance concrete
# BON : depend de l'abstraction class ServiceCommande: def __init__(self, notificateur): # on recoit l'abstraction self.notificateur = notificateur
Crée un système de notifications : - Notificateur (ABC) avec envoyer(message) abstraite - NotificateurEmail(Notificateur) : envoyer retourne 'Email: {message}' - NotificateurSMS(Notificateur) : envoyer retourne 'SMS: {message}' - ServiceCommande(notificateur) : depend de l'abstraction - confirmer(numéro) appelle self.notificateur.envoyer('Commande {numéro} confirmee') et retourne le résultat
Exemple : s = ServiceCommande(NotificateurEmail()) s.confirmer('001') # 'Email: Commande 001 confirmee' s = ServiceCommande(NotificateurSMS()) s.confirmer('002') # 'SMS: Commande 002 confirmee'
Tests (3/4)
Notification Email
s = ServiceCommande(NotificateurEmail())
assert s.confirmer('001') == 'Email: Commande 001 confirmée'
Notification SMS
s = ServiceCommande(NotificateurSMS())
assert s.confirmer('002') == 'SMS: Commande 002 confirmée'
Interchangeable
for notif, prefix in [(NotificateurEmail(), 'Email'), (NotificateurSMS(), 'SMS')]:
s = ServiceCommande(notif)
result = s.confirmer('X')
assert result.startswith(prefix)
+ 0 tests cachés
Indices (3 disponibles)
Solution officielle
from abc import ABC, abstractmethod
class Notificateur(ABC):
@abstractmethod
def envoyer(self, message):
pass
class NotificateurEmail(Notificateur):
def envoyer(self, message):
return f'Email: {message}'
class NotificateurSMS(Notificateur):
def envoyer(self, message):
return f'SMS: {message}'
class ServiceCommande:
def __init__(self, notificateur):
self.notificateur = notificateur
def confirmer(self, numéro):
return self.notificateur.envoyer(f'Commande {numéro} confirmée')