Behavioral patterns are concerned with how objects communicate and divide responsibility for behavior at runtime. Strategy defines a family of interchangeable algorithms behind one interface, and lets the active one be swapped at runtime — the direct alternative to a long, ever-growing if/switch chain (already shown as the fix for an Open/Closed violation earlier in this reference).
public interface IShippingStrategy
{
decimal CalculateCost(Order order);
}
public class StandardShipping : IShippingStrategy
{
public decimal CalculateCost(Order order) => 5.99m;
}
public class ExpressShipping : IShippingStrategy
{
public decimal CalculateCost(Order order) => 19.99m;
}
public class FreeShippingOverThreshold : IShippingStrategy
{
public decimal CalculateCost(Order order) => order.Total > 50 ? 0m : 5.99m;
}
public class Checkout
{
private readonly IShippingStrategy _shippingStrategy;
public Checkout(IShippingStrategy shippingStrategy) => _shippingStrategy = shippingStrategy;
public decimal GetTotal(Order order) => order.Total + _shippingStrategy.CalculateCost(order);
}
// The active strategy is chosen at runtime and passed in — Checkout itself never changes.
var checkout = new Checkout(new FreeShippingOverThreshold());