Strategy Pattern pour algorithmes

Découvrez comment le pattern Strategy permet de rendre vos algorithmes interchangeables et maintenables. Une approche élégante pour découpler le comportement de vos classes et gagner en flexibilité.

Olivier Dupuy
23 juillet 2025

91

Vues

0

Commentaires

2

Min de lecture

Le Strategy Pattern est l'un des patrons de conception comportementaux les plus utiles en programmation orientée objet. Il permet d'encapsuler une famille d'algorithmes interchangeables et de les rendre indépendants des clients qui les utilisent. Dans cet article, nous allons explorer en détail ce pattern essentiel et voir comment l'implémenter efficacement en C# et .NET.

Comprendre le Strategy Pattern

Le Strategy Pattern définit une famille d'algorithmes, encapsule chacun d'eux et les rend interchangeables. Il permet de faire varier indépendamment les algorithmes des clients qui les utilisent. Ce pattern est particulièrement utile lorsque :

  • Vous avez une famille d'algorithmes similaires
  • Vous devez pouvoir changer d'algorithme dynamiquement
  • Vous souhaitez isoler la logique algorithmique du code qui l'utilise

Implémentation en C#

Voici un exemple concret d'implémentation du Strategy Pattern pour gérer différentes stratégies de calcul de prix :


// Interface définissant le contrat pour toutes les stratégies
public interface IPricingStrategy
{
    decimal CalculatePrice(decimal basePrice);
}

// Implémentation concrète pour le prix standard public class RegularPricingStrategy : IPricingStrategy { public decimal CalculatePrice(decimal basePrice) { return basePrice; } }

// Implémentation pour les prix soldés public class DiscountPricingStrategy : IPricingStrategy { private readonly decimal _discountPercentage;

public DiscountPricingStrategy(decimal discountPercentage) { _discountPercentage = discountPercentage; }

public decimal CalculatePrice(decimal basePrice) { return basePrice (1 - _discountPercentage / 100); } }

// Contexte qui utilise la stratégie public class PriceCalculator { private IPricingStrategy _pricingStrategy;

public PriceCalculator(IPricingStrategy strategy) { _pricingStrategy = strategy; }

public void SetStrategy(IPricingStrategy strategy) { _pricingStrategy = strategy; }

public decimal CalculateFinalPrice(decimal basePrice) { return _pricingStrategy.CalculatePrice(basePrice); } }

Utilisation et Tests

Voici comment utiliser et tester ce pattern :


[Fact]
public void TestPricingStrategies()
{
    // Arrange
    var calculator = new PriceCalculator(new RegularPricingStrategy());
    var basePrice = 100m;

// Act & Assert - Prix régulier var regularPrice = calculator.CalculateFinalPrice(basePrice); Assert.Equal(100m, regularPrice);

// Act & Assert - Prix soldé calculator.SetStrategy(new DiscountPricingStrategy(20)); var discountedPrice = calculator.CalculateFinalPrice(basePrice); Assert.Equal(80m, discountedPrice); }

Bonnes Pratiques

  • Gardez les stratégies immutables quand c'est possible
  • Utilisez l'injection de dépendances pour gérer les stratégies
  • Documentez clairement le comportement de chaque stratégie
  • Évitez les dépendances externes dans les stratégies

Intégration avec ASP.NET Core

Voici comment intégrer le pattern dans une application ASP.NET Core :


public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped();
        services.AddScoped();
    }
}

[ApiController] [Route("[controller]")] public class PricingController : ControllerBase { private readonly PriceCalculator _calculator;

public PricingController(PriceCalculator calculator) { _calculator = calculator; }

[HttpGet("{price}")] public ActionResult GetPrice(decimal price) { return _calculator.CalculateFinalPrice(price); } }

Considérations de Performance

Pour optimiser les performances :

  • Utilisez le pooling d'objets pour les stratégies fréquemment utilisées
  • Évitez de créer de nouvelles instances de stratégies inutilement
  • Mettez en cache les résultats des calculs coûteux

Gestion des Erreurs

Implémentez une gestion d'erreurs robuste :


public class PriceCalculator
{
    private IPricingStrategy _pricingStrategy;

public decimal CalculateFinalPrice(decimal basePrice) { try { if (basePrice < 0) throw new ArgumentException("Le prix de base ne peut pas être négatif");

return _pricingStrategy?.CalculatePrice(basePrice) ?? throw new InvalidOperationException("Aucune stratégie de prix n'est définie"); } catch (Exception ex) { // Log l'erreur throw new PriceCalculationException("Erreur lors du calcul du prix", ex); } } }

Conclusion

Le Strategy Pattern est un outil puissant pour gérer des familles d'algorithmes interchangeables. Il permet de :

  • Découpler les algorithmes de leur utilisation
  • Faciliter l'ajout de nouveaux comportements
  • Améliorer la maintenabilité du code
  • Respecter le principe Open/Closed

En suivant les bonnes pratiques et en comprenant les cas d'usage appropriés, vous pourrez tirer le meilleur parti de ce pattern dans vos applications .NET.

Partager cet article
42
12

Commentaires (0)

Rejoignez la discussion

Connectez-vous pour partager votre avis et échanger avec la communauté

Première discussion

Soyez le premier à partager votre avis sur cet article !

À propos de l'auteur
Olivier Dupuy

Développeur passionné et créateur de contenu technique. Expert en développement web moderne avec ASP.NET Core, JavaScript, et technologies cloud.

Profil
Articles similaires
API versioning strategies
02 août 2025 0
C# & .NET
Cryptographie post-quantique
02 août 2025 0
C# & .NET
Géolocalisation et cartes interactives
02 août 2025 0
C# & .NET
Navigation rapide
Commentaires (0)