Patron Stratégie
Fait partie de la section Programmation Orientée Objet du Journey C# de Coddy — leçon 55 sur 70.
Le patron Stratégie est un patron de conception comportemental qui vous permet de définir une famille d'algorithmes, d'encapsuler chacun d'eux dans sa propre classe et de les rendre interchangeables au moment de l'exécution. Au lieu de coder le comportement en dur, vous injectez la stratégie souhaitée dans un objet.
Le patron se compose de trois parties : une interface de stratégie qui définit le contrat de l'algorithme, des classes de stratégie concrètes qui implémentent différents comportements, et une classe de contexte qui utilise une stratégie :
public interface IPaymentStrategy
{
void Pay(decimal amount);
}
public class CreditCardPayment : IPaymentStrategy
{
public void Pay(decimal amount) =>
Console.WriteLine($"Paid {amount} via Credit Card");
}
public class PayPalPayment : IPaymentStrategy
{
public void Pay(decimal amount) =>
Console.WriteLine($"Paid {amount} via PayPal");
}
public class ShoppingCart
{
private IPaymentStrategy _paymentStrategy;
public void SetPaymentMethod(IPaymentStrategy strategy)
{
_paymentStrategy = strategy;
}
public void Checkout(decimal total)
{
_paymentStrategy.Pay(total);
}
}Le contexte (ShoppingCart) ne sait pas quelle méthode de paiement il utilise - il appelle simplement Pay() sur la stratégie qui a été fournie :
var cart = new ShoppingCart();
cart.SetPaymentMethod(new CreditCardPayment());
cart.Checkout(99.99m); // Paid 99.99 via Credit Card
cart.SetPaymentMethod(new PayPalPayment());
cart.Checkout(49.99m); // Paid 49.99 via PayPalLe pattern Strategy élimine la logique conditionnelle complexe. Ajouter une nouvelle méthode de paiement signifie créer une nouvelle classe qui implémente IPaymentStrategy - aucun changement n'est nécessaire dans ShoppingCart. Cela rend votre code ouvert à l'extension mais fermé à la modification.
Défi
FacileConstruisons un calculateur de frais d'expédition en utilisant le motif de conception Strategy (Stratégie). Différentes méthodes d'expédition ont des algorithmes de tarification différents, et votre système doit permettre de basculer entre eux au moment de l'exécution sans modifier la logique principale de traitement des commandes.
Vous organiserez votre code sur trois fichiers :
ShippingStrategy.cs: Définissez une interfaceIShippingStrategydans l'espace de nomsShippingavec une méthodeCalculateCost(double weight)qui retourne undouble. Créez ensuite trois classes de stratégie concrètes :StandardShipping- calcule le coût commeweight * 1.5ExpressShipping- calcule le coût commeweight * 3.0 + 5.0(inclut des frais express fixes)OvernightShipping- calcule le coût commeweight * 5.0 + 10.0(service premium avec des frais de base plus élevés)
OrderProcessor.cs: Créez une classeOrderProcessordans le même espace de noms. C'est votre classe de contexte qui utilise une stratégie d'expédition. Elle doit avoir :- Un champ privé pour stocker la
IShippingStrategyactuelle - Une méthode
SetShippingMethod(IShippingStrategy strategy)pour changer la stratégie d'expédition - Une méthode
ProcessOrder(double weight)qui utilise la stratégie actuelle pour calculer et retourner les frais d'expédition
- Un champ privé pour stocker la
Program.cs: Rassemblez le tout en créant unOrderProcessoret en démontrant comment vous pouvez échanger les stratégies d'expédition au moment de l'exécution. Le même processeur peut calculer les coûts en utilisant différents algorithmes simplement en changeant sa stratégie.
Vous recevrez deux entrées :
- Le type de méthode d'expédition :
"standard","express", ou"overnight" - Le poids du colis sous forme de nombre décimal (par exemple,
4.5)
Créez un OrderProcessor, définissez la stratégie d'expédition appropriée en fonction du type d'entrée, puis traitez la commande et affichez le coût calculé.
Par exemple, si les entrées sont "express" et 4.5, la sortie devrait être :
18.5Cela démontre la puissance du motif Strategy - votre OrderProcessor ne contient aucune logique de calcul d'expédition lui-même. Il délègue simplement à la stratégie qui lui a été donnée, ce qui facilite l'ajout de nouvelles méthodes d'expédition (comme DroneDelivery) sans modifier le processeur du tout !
Aide-mémoire
Le pattern Strategy (ou patron de stratégie) est un patron de conception comportemental qui définit une famille d'algorithmes, encapsule chacun d'eux dans sa propre classe et les rend interchangeables au moment de l'exécution.
Le patron se compose de trois parties :
- Interface Strategy : définit le contrat de l'algorithme
- Classes de stratégie concrètes : implémentent différents comportements
- Classe de contexte : utilise une stratégie sans connaître ses détails d'implémentation
Exemple de structure :
// Interface Strategy
public interface IPaymentStrategy
{
void Pay(decimal amount);
}
// Stratégies concrètes
public class CreditCardPayment : IPaymentStrategy
{
public void Pay(decimal amount) =>
Console.WriteLine($"Paid {amount} via Credit Card");
}
public class PayPalPayment : IPaymentStrategy
{
public void Pay(decimal amount) =>
Console.WriteLine($"Paid {amount} via PayPal");
}
// Classe de contexte
public class ShoppingCart
{
private IPaymentStrategy _paymentStrategy;
public void SetPaymentMethod(IPaymentStrategy strategy)
{
_paymentStrategy = strategy;
}
public void Checkout(decimal total)
{
_paymentStrategy.Pay(total);
}
}Utilisation - changement de stratégie au moment de l'exécution :
var cart = new ShoppingCart();
cart.SetPaymentMethod(new CreditCardPayment());
cart.Checkout(99.99m); // Paid 99.99 via Credit Card
cart.SetPaymentMethod(new PayPalPayment());
cart.Checkout(49.99m); // Paid 49.99 via PayPalAvantages :
- Élimine la logique conditionnelle complexe
- Ouvert à l'extension, fermé à la modification
- L'ajout de nouvelles stratégies nécessite uniquement la création de nouvelles classes, sans modification du code existant
Essayez vous-même
using System;
using Shipping;
class Program
{
public static void Main(string[] args)
{
// Lire l'entrée
string shippingType = Console.ReadLine();
double weight = Convert.ToDouble(Console.ReadLine());
// TODO: Créer une instance de OrderProcessor
// TODO: En fonction de shippingType ("standard", "express", ou "overnight"),
// créer la stratégie d'expédition appropriée et la définir sur le processeur
// TODO: Traiter la commande et afficher le coût calculé
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesEspaces de noms et directivesIntro aux classes et objetsLe mot-clé 'this'Méthodes et paramètresChamps vs PropriétésConstructeursInitialiseurs d'objetsRécapitulatif - Calculatrice simple4Héritage
Syntaxe de base de l'héritage (:)Le mot-clé 'base'Mots-clés Virtual & OverrideClasses scelléesLa classe de base 'object'Récapitulatif - Hiérarchie des employés7Fonctionnalités avancées
Surcharge d'opérateursIndexeurs (this[])Redéfinition de ToString()Méthodes d'extensionRécapitulatif - Liste personnalisée10Patrons de conception - Partie 1
Introduction aux patrons de conceptionSingleton Thread-SafePatron FabriquePatron Observateur (Événements)Patron Stratégie2Propriétés et membres statiques
Propriétés auto-implémentéesPropriétés en lecture/écriture seuleChamps et méthodes statiquesClasses statiquesMembres à corps d'expression5Polymorphisme & Interfaces
Polymorphisme : Compilation vs ExécutionInterface vs Classe AbstraiteInterfaces MultiplesInterfaces ExplicitesUpcasting & DowncastingRécapitulatif - Calculateur de Formes8Concepts avancés de la POO
Composition plutôt qu'héritageGénériques (Classes et Méthodes)Délégués et ÉvénementsAttributs et RéflexionIDisposable et l'instruction usingBases de l'Injection de Dépendances11Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode TemplatePatron ÉtatPatron Composite3Architecture des classes
Données d'instance vs statiquesMots-clés 'readonly' & 'const'Champs de supportRécapitulatif - Gestionnaire de compte bancaire6Encapsulation
Modificateurs d'accèsPropriétés pour l'encapsulationImplémentation du masquage de donnéesPatterns d'immuabilitéRécapitulatif - Dossiers d'étudiants12Projet : Système de gestion de bibliothèque
Structure du projetModèles Livre et Utilisateur