Patrons de conception
#Patrons de conception
Les patrons de conception (design patterns) sont des solutions classiques à des problèmes récurrents en développement logiciel. Ils fournissent des schémas de conception réutilisables qui aident à structurer le code, améliorer sa lisibilité et sa maintenabilité.
#Pattern Stratégie
Le pattern Stratégie permet de définir une famille d'algorithmes, de les encapsuler et de les rendre interchangeables. Cela permet de modifier le comportement d'un algorithme sans changer le code client.
#Exemple (Python)
1from abc import ABC, abstractmethod2 3# Interface commune4class Strategy(ABC):5 @abstractmethod6 def do_operation(self, a, b):7 pass8 9# Implémentations concrètes10class AddStrategy(Strategy):11 def do_operation(self, a, b):12 return a + b13 14class SubStrategy(Strategy):
#Pattern Observateur
Le pattern Observateur définit une dépendance un-à-plusieurs entre objets, de sorte que lorsqu'un objet change d'état, tous ses dépendants en sont notifiés automatiquement.
#Exemple (Python)
1class Subject:2 def __init__(self):3 self._observers = []4 self._state = None5 6 def attach(self, observer):7 self._observers.append(observer)8 9 def notify(self):10 for observer in self._observers:11 observer.update(self._state)12 13 def set_state(self, state):14 self._state = state
#Pattern Fabrique
Le pattern Fabrique définit une interface pour créer un objet, mais laisse les sous-classes décider quelle classe instancier. Il permet de déléguer l'instanciation aux sous-classes.
#Exemple (Python)
1from abc import ABC, abstractmethod2 3class Product(ABC):4 @abstractmethod5 def operation(self):6 pass7 8class ConcreteProductA(Product):9 def operation(self):10 return "Produit A"11 12class ConcreteProductB(Product):13 def operation(self):14 return "Produit B"
#Exercice : Système de Logging
Implémentez un système de logging simple en utilisant le pattern Observateur. Le système doit permettre à différents modules de s'abonner aux messages de log et d'y réagir (affichage dans la console, écriture dans un fichier, etc.).
#Instructions
- Créez une classe
Logger
qui agit comme le sujet. - Créez une interface
LogObserver
avec une méthodeupdate(message)
. - Implémentez des observateurs concrets comme
ConsoleLogger
etFileLogger
. - Permettez aux observateurs de s'abonner et de se désabonner du
Logger
. - Ajoutez une méthode
log(message)
dansLogger
qui notifie tous les observateurs.
#Exemple de code de départ
1class Logger:2 def __init__(self):3 self._observers = []4 5 def attach(self, observer):6 self._observers.append(observer)7 8 def detach(self, observer):9 self._observers.remove(observer)10 11 def log(self, message):12 for observer in self._observers:13 observer.update(message)14
#Bénéfices et limites
#Bénéfices
- Réutilisabilité : Les patterns offrent des solutions éprouvées à des problèmes courants.
- Maintenabilité : Un code structuré selon des patterns est plus facile à comprendre et à modifier.
- Communication : Les développeurs partagent un langage commun pour discuter de la conception.
#Limites
- Sur-conception : Utiliser des patterns partout peut complexifier inutilement le code.
- Apprentissage : Maîtriser les patterns demande du temps et de la pratique.
- Adaptation : Les patterns doivent parfois être adaptés au contexte spécifique d'un projet.
Les patrons de conception sont des outils puissants, mais leur utilisation doit être guidée par le bon sens et les besoins concrets du projet.
1