Menu
Coddy logo textTech

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 PayPal

Le 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.

challenge icon

Défi

Facile

Construisons 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 interface IShippingStrategy dans l'espace de noms Shipping avec une méthode CalculateCost(double weight) qui retourne un double. Créez ensuite trois classes de stratégie concrètes :
    • StandardShipping - calcule le coût comme weight * 1.5
    • ExpressShipping - calcule le coût comme weight * 3.0 + 5.0 (inclut des frais express fixes)
    • OvernightShipping - calcule le coût comme weight * 5.0 + 10.0 (service premium avec des frais de base plus élevés)
  • OrderProcessor.cs : Créez une classe OrderProcessor dans 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 IShippingStrategy actuelle
    • 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
  • Program.cs : Rassemblez le tout en créant un OrderProcessor et 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.5

Cela 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 PayPal

Avantages :

  • É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é
    }
}
quiz iconTestez-vous

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