Menu
Coddy logo textTech

Strategy Pattern

Part of the Object Oriented Programming section of Coddy's C# journey — lesson 55 of 70.

The Strategy pattern is a behavioral pattern that lets you define a family of algorithms, encapsulate each one in its own class, and make them interchangeable at runtime. Instead of hardcoding behavior, you inject the desired strategy into an object.

The pattern consists of three parts: a strategy interface that defines the algorithm contract, concrete strategy classes that implement different behaviors, and a context class that uses a strategy:

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);
    }
}

The context (ShoppingCart) doesn't know which payment method it's using - it just calls Pay() on whatever strategy was provided:

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

The Strategy pattern eliminates complex conditional logic. Adding a new payment method means creating a new class that implements IPaymentStrategy - no changes needed in ShoppingCart. This makes your code open for extension but closed for modification.

challenge icon

Challenge

Easy

Let's build a shipping cost calculator using the Strategy pattern. Different shipping methods have different pricing algorithms, and your system should allow switching between them at runtime without changing the core order processing logic.

You'll organize your code across three files:

  • ShippingStrategy.cs: Define an IShippingStrategy interface in the Shipping namespace with a method CalculateCost(double weight) that returns a double. Then create three concrete strategy classes:
    • StandardShipping - calculates cost as weight * 1.5
    • ExpressShipping - calculates cost as weight * 3.0 + 5.0 (includes a flat express fee)
    • OvernightShipping - calculates cost as weight * 5.0 + 10.0 (premium service with higher base fee)
  • OrderProcessor.cs: Create an OrderProcessor class in the same namespace. This is your context class that uses a shipping strategy. It should have:
    • A private field to hold the current IShippingStrategy
    • A SetShippingMethod(IShippingStrategy strategy) method to change the shipping strategy
    • A ProcessOrder(double weight) method that uses the current strategy to calculate and return the shipping cost
  • Program.cs: Bring everything together by creating an OrderProcessor and demonstrating how you can swap shipping strategies at runtime. The same processor can calculate costs using different algorithms simply by changing its strategy.

You will receive two inputs:

  • The shipping method type: standard, express, or overnight
  • The package weight as a decimal number (e.g., 4.5)

Create an OrderProcessor, set the appropriate shipping strategy based on the input type, then process the order and print the calculated cost.

For example, if the inputs are express and 4.5, the output should be:

18.5

This demonstrates the Strategy pattern's power - your OrderProcessor doesn't contain any shipping calculation logic itself. It simply delegates to whatever strategy it's been given, making it easy to add new shipping methods (like DroneDelivery) without modifying the processor at all!

Cheat sheet

The Strategy pattern is a behavioral pattern that defines a family of algorithms, encapsulates each one in its own class, and makes them interchangeable at runtime.

The pattern consists of three parts:

  • Strategy interface: defines the algorithm contract
  • Concrete strategy classes: implement different behaviors
  • Context class: uses a strategy without knowing its implementation details

Example structure:

// Strategy interface
public interface IPaymentStrategy
{
    void Pay(decimal amount);
}

// Concrete strategies
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");
}

// Context class
public class ShoppingCart
{
    private IPaymentStrategy _paymentStrategy;
    
    public void SetPaymentMethod(IPaymentStrategy strategy)
    {
        _paymentStrategy = strategy;
    }
    
    public void Checkout(decimal total)
    {
        _paymentStrategy.Pay(total);
    }
}

Usage - switching strategies at runtime:

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

Benefits:

  • Eliminates complex conditional logic
  • Open for extension, closed for modification
  • Adding new strategies requires only creating new classes, no changes to existing code

Try it yourself

using System;
using Shipping;

class Program
{
    public static void Main(string[] args)
    {
        // Read input
        string shippingType = Console.ReadLine();
        double weight = Convert.ToDouble(Console.ReadLine());

        // TODO: Create an OrderProcessor instance

        // TODO: Based on shippingType ("standard", "express", or "overnight"),
        // create the appropriate shipping strategy and set it on the processor

        // TODO: Process the order and print the calculated cost
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming