Le principe de responsabilité unique SRP en Python
Auteur
Elie TerrienSi vous avez des questions ou des commentaires, n'hésitez pas à les laisser en bas de page. Je serai ravi d'y répondre.
1. Qu'est-ce que le principe de responsabilité unique (SRP) ?
Le principe de responsabilité unique (SRP) est l'un des principes SOLID. Il consiste à créer des classes distinctes si elles changent pour des raisons différentes. Par exemple, si une classe gère des utilisateurs avec des roles différents, il est préférable de créer une classe par role (admin et customer). De cette manière, si les règles de gestion changent pour les admins, cela n'impactera pas les customers.
2. Pourquoi utiliser le principe de responsabilité unique (SRP) ?
Le principe SRP est une méthode de conception de classes. C'est un principe de base de la programmation orientée objet et du Clean Code.
Voici les avantages de ce principe sur les classes :
Facilité accrue de maintenance. Modifier une règle de gestion ne provoque pas d'effets indésirables ou de régressions sur une autre règle de gestion.
Tests de méthodes plus aisés. En évitant de combiner plusieurs règles de gestion dans une seule classe, vous n'avez pas à tester toutes ces règles à chaque fois.
Réutilisation plus aisée des classes. Lorsque vous avez besoin d'employer une règle de gestion dans une autre classe, cela peut se faire sans nécessiter de dupliquer le code.
Simplification de la documentation des classes. Documenter une classe qui se concentre sur une unique fonctionnalité est plus aisé. Le code devient plus simple à lire et à comprendre.
3. Exemple de code Python ne respectant pas le principe de responsabilité unique (SRP)
Imaginons que vous ayez besoin de créer un système de gestion d'utilisateurs. Vous devez gérer la mise à jour de l'adresse d'un utilisateur et l'envoi d'email de bienvenue. Voici un exemple de code qui ne respecte pas le principe SRP :
class UserManager:
def __init__(self, user_data):
self.user_data = user_data
def change_user_address(self, new_address):
self.user_data['address'] = new_address
print(f"Address updated to {new_address}")
self.send_email("Your address has been updated.")
def send_email(self, email_content):
# Code to send email
print(f"Email sent to {self.user_data['email']}: {email_content}")
Dans cet exemple, la méthode change_user_address
modifie l'adresse de l'utilisateur et envoie un email de confirmation. Si vous souhaitez envoyer un email de bienvenue, vous pouvez appeler la méthode send_email
directement. Cela implique d'ajouter un paramètre email_type
à la méthode send_email
pour différencier les emails de bienvenue des emails de confirmation. Cela rend la méthode plus complexe et plus difficile à tester.
class UserManager:
def __init__(self, user_data):
self.user_data = user_data
def change_user_address(self, new_address):
self.user_data['address'] = new_address
# Envoi d'un email de confirmation
self.send_email("Your address has been updated.", "address_change")
def send_email(self, email_content, email_type=None):
# Test du type d'email
if email_type == "address_change":
# Construction du contenu de l'email
email_content += f"\nNew Address: {self.user_data['address']}"
# Logique supplémentaire pour l'envoi d'email de confirmation
# ... exemple : mise à jour du pseudo de l'utilisateur
elif email_type == "welcome":
# Construction du contenu de l'email de bienvenue
# ... exemple : ajout d'un lien de confirmation
# Code générique pour l'envoi d'email
print(f"Email sent to {self.user_data['email']}: {email_content}")
# Example usage
user_data = {'name': 'John Doe', 'email': '[email protected]', 'address': '123 Main St'}
manager = UserManager(user_data)
manager.change_user_address('456 Elm St')
manager.send_email("Welcome to our website!", "welcome")
4. Exemple de code Python respectant le principe de responsabilité unique (SRP)
Maintenant, voici un exemple de code qui respecte le principe SRP. Toujours dans le cas de la gestion d'utilisateurs, nous avons créé une classe UserDataManager
qui gère les données des utilisateurs et une classe EmailNotificationManager
qui gère l'envoi d'email.
class UserDataManager:
"""
Classe pour gérer les données des utilisateurs.
"""
def __init__(self, user_data):
self.user_data = user_data
def change_user_address(self, new_address):
self.user_data['address'] = new_address
print(f"Address updated to {new_address}")
class EmailNotificationManager:
"""
Classe pour envoyer des notifications aux utilisateurs
par email.
"""
def __init__(self, user_data):
self.user_data = user_data
def send_email(self, email_content):
# Code to send email
print(f"Email sent to {self.user_data['email']}: {email_content}")
Exemple de mise à jour de l'adresse utilisateur à l'aide des classes SRP
Pour respecter les règles de gestion, nous devons : mettre à jour l'adresse de l'utilisateur et envoyer un email de confirmation.
Nous allons donc créer une instance de UserDataManager
et une instance de EmailNotificationManager
. Ensuite, nous allons appeler les méthodes change_user_address
et send_email
de chaque instance.
user_data = {'name': 'John Doe', 'email': '[email protected]', 'address': '123 Main St'}
user_data_manager = UserDataManager(user_data)
email_manager = EmailNotificationManager(user_data['email'])
# Update address
user_data_manager.change_user_address('456 Elm St')
# Send notification
email_manager.send_email("Your address has been updated.")
Explications du principe SRP en Python dans cet exemple
UserDataManager : cette classe gère uniquement les données des utilisateurs. Si les règles de gestion des données des utilisateurs changent, vous n'avez pas besoin de modifier la classe EmailNotificationManager
.
EmailNotificationManager : cette classe gère uniquement l'envoi d'email. Si les règles de gestion de l'envoi d'email changent, vous n'avez pas besoin de modifier la classe UserDataManager
.
Découplage des classes : les classes UserDataManager
et EmailNotificationManager
sont indépendantes. Vous pouvez les réutiliser facilement. Par exemple, si vous ne souhaitez pas notifier un administrateur de la mise à jour de son adresse email, vous pouvez utiliser uniquement la classe UserDataManager
.
Tests unitaires plus simples : les classes sont plus simples à tester. Vous pouvez tester la classe UserDataManager
sans avoir à tester la classe EmailNotificationManager
et vice versa.
Le principe SRP comporte de nombreux avantages. Utilisez-le dans votre code Python pour concevoir des applications plus simples à maintenir et à tester.