Understanding the Need:
Consider a scenario where the behavior of an algorithm must be dynamically selected at runtime. This is a common challenge in software development, and the knee-jerk reaction might involve a plethora of conditional statements. However, the Strategy Pattern offers an elegant alternative.
Anatomy of Strategy Pattern:
The Strategy Pattern involves defining a family of algorithms, encapsulating each of them, and making them interchangeable. This enables the client to choose a specific algorithm at runtime. Let’s delve into the implementation.
Theoretical Case: Example of Implementation
Begin by creating a context class that includes the strategy:
using System;
public class Context
{
private IStrategy _strategy;
public Context(IStrategy strategy)
{
this.SetStrategy(strategy);
}
public void SetStrategy(IStrategy strategy)
{
Console.WriteLine($"Context: Set {strategy.GetType().Name} strategy");
this._strategy = strategy;
}
public void ExecuteStrategy()
{
this._strategy.DoSomething();
}
}
Define an interface for the strategies:
public interface IStrategy
{
void DoSomething();
}
Implement concrete strategy classes:
public class ConcreteStrategyA : IStrategy
{
public void DoSomething()
{
Console.WriteLine("ConcreteStrategyA is performing the strategy.");
}
}
public class ConcreteStrategyB : IStrategy
{
public void DoSomething()
{
Console.WriteLine("ConcreteStrategyB is performing the strategy.");
}
}
// Add more strategies as needed
In the main program, instantiate the context and set and execute different strategies:
public class Program
{
public static void Main(string[] args)
{
var context = new Context(new ConcreteStrategyA());
context.ExecuteStrategy();
context.SetStrategy(new ConcreteStrategyB());
context.ExecuteStrategy();
}
}
Upon execution, you’ll witness the dynamic change of strategies.
Real-world Scenario: E-Commerce Discount Strategies
Let’s apply the Strategy Pattern in a real-world context, such as an e-commerce platform offering various discount strategies.
public interface IDiscountStrategy
{
double ApplyDiscount(double originalPrice);
}
public class RegularCustomerDiscount : IDiscountStrategy
{
public double ApplyDiscount(double originalPrice)
{
return originalPrice * 0.95; // 5% discount for regular customers
}
}
public class PrimeMemberDiscount : IDiscountStrategy
{
public double ApplyDiscount(double originalPrice)
{
return originalPrice * 0.85; // 15% discount for prime members
}
}
In this scenario, the checkout process serves as the context class, dynamically applying different discount strategies based on the customer type:
public class CheckoutProcess(IDiscountStrategy discountStrategy)
{
public double ProcessOrder(double originalPrice)
{
// Additional order processing logic can be added here
return discountStrategy.ApplyDiscount(originalPrice);
}
}
Now, in your main program, you can use the CheckoutProcess
class to handle orders with different discount strategies.
Conclusion:
The Strategy Pattern emerges as a cornerstone in managing varying algorithms or behaviors within a system. By encapsulating strategies and allowing dynamic switching, this pattern not only fosters flexibility and maintainability but also aligns with SOLID principles.
Laisser un commentaire