Chain of Responsibility Pattern vs Pipeline Pattern
1. Chain of Responsibility Pattern
- Objectif : Permet à plusieurs objets (handlers) de traiter une requête de manière séquentielle, chaque handler ayant la possibilité de la traiter ou de la passer au suivant.
- Cas d'utilisation : Idéal pour des systèmes où plusieurs étapes indépendantes doivent traiter ou ignorer une requête, comme les middlewares dans Laravel.
- Exemple : Gestion des exceptions dans une application Laravel, où chaque exception est traitée par un handler jusqu'à trouver celui qui peut gérer l'exception.
2. Pipeline Pattern
- Objectif : Organiser une série d'opérations ou transformations successives sur des données, chaque étape recevant une entrée, la transformant, et la passant à l'étape suivante.
- Cas d'utilisation : Utilisé pour les processus où chaque étape doit transformer ou modifier les données avant de passer à la suivante, comme dans les middlewares ou pour appliquer des transformations successives sur une commande.
- Exemple : Traitement d'une commande dans une application Laravel où des étapes comme l'application de réductions, la vérification du stock, et le calcul des taxes sont exécutées successivement.
Comparaison directe :
| Caractéristique | Chain of Responsibility Pattern | Pipeline Pattern |
|---|---|---|
| Traitement de la requête | Chaque handler peut traiter ou passer la requête au suivant. | Chaque étape transforme les données avant de les passer. |
| Séquence des étapes | Séquentielle, mais certains handlers peuvent arrêter la chaîne. | Toutes les étapes sont exécutées l'une après l'autre. |
| Utilisation principale | Gestion des responsabilités comme les exceptions ou les erreurs. | Transformation de données à travers plusieurs étapes successives. |
| Exemple Laravel | Système de gestion des exceptions dans Handler.php. |
Application des middlewares HTTP ou traitement de commandes. |
Exemples
Imaginons que nous traitions une requête d'utilisateur dans une application Laravel. La requête peut soit déclencher un traitement ou être transformée à travers plusieurs étapes :
1. Chain of Responsibility Pattern
La requête passe à travers plusieurs handlers, chacun ayant la possibilité de la traiter ou de la transmettre au suivant.
class ValidateRequestHandler {
public function handle($request) {
if (empty($request['email'])) {
throw new Exception('Email is required');
}
// Pass to next handler
return $next->handle($request);
}
}
class AuthenticateHandler {
public function handle($request) {
if ($request['email'] !== 'user@example.com') {
throw new Exception('User not authenticated');
}
// Pass to next handler
return $next->handle($request);
}
}
2. Pipeline Pattern
La requête est transformée à chaque étape, avec des opérations appliquées successivement.
class ApplyDiscount {
public function handle($order, $next) {
$order['total'] *= 0.9; // Apply 10% discount
return $next($order);
}
}
class CalculateTax {
public function handle($order, $next) {
$order['tax'] = $order['total'] * 0.15;
$order['total'] += $order['tax'];
return $next($order);
}
}
Explications
Dans le Chain of Responsibility Pattern, chaque étape (handler) peut décider de traiter ou de passer la requête à la suivante. La chaîne peut s'arrêter à tout moment si une étape gère complètement la requête.
Dans le Pipeline Pattern, chaque étape modifie ou transforme les données avant de les passer à l'étape suivante, créant un flux continu de transformations sur les données jusqu'à la fin du pipeline.
Cas d'utilisation des patterns
Chain of Responsibility : Utile pour des systèmes où chaque étape peut ignorer ou traiter la requête. Par exemple, pour gérer des exceptions ou des autorisations.
Pipeline : Convient aux processus de transformation continue où chaque étape doit appliquer une opération ou une modification aux données, comme dans le traitement d'une commande ou les transformations de données.
Conclusion
Bien que les deux patterns soient comportementaux et se basent sur une exécution séquentielle, ils répondent à des besoins différents :
Le Chain of Responsibility Pattern permet à chaque étape de choisir si elle veut traiter ou passer la requête, tandis que le Pipeline Pattern garantit que chaque étape applique une transformation avant de passer les données.
Choisissez le Chain of Responsibility pour des systèmes qui doivent décider s'ils traitent ou non une requête. Optez pour le Pipeline Pattern lorsque plusieurs transformations doivent être appliquées successivement sur des données.