The Strategy Design Pattern in C#

The strategy design pattern allows you to encapsulate a group or family of algorithms, making them interchangeable. This allows code to determine which strategy to use at runtime. The strategy pattern is a behavioral pattern and is one of the original design patterns defined by the Gang of Four (GoF).

 

What Problem Does It Solve?

The strategy pattern allows you to write less fragile and coupled code. Instead of planning for every eventuality and creating code structures to deal with them, the strategy pattern gives you a clearly defined and easy to implement mechanism for algorithm selection at runtime.

The Actors

Billing Contract

The billing contract is a fairly simple interface to enforce behavior across all contracts.

Listing 1.1 – IBillingContract.cs
public interface IBillingStrategy.cs
{
    DateTime GetDueDate();
    void SendBill(string[] address);
}

Abstract Billing Strategy

The Billing Strategy is the only object that inherits from the IBillingStrategy interface. However, the GetDueDate method is implemented as abstract so each child of the abstract billing strategy must create their own implementation.

Listing 1.2 – BillingStrategy.cs
public abstract class BillingStrategy : IBillingStrategy
{
    public abstract DateTime GetDueDate();

    public virtual void SendBill(string[] address)
    {
        Console.WriteLine("Sending Bill to: ");

        foreach(string addressPart in address)
        {
            Console.WriteLine(addressPart);
        }

        Console.WriteLine($"Due Date: {GetDueDate().ToShortDateString()}");
        Console.WriteLine();
    }
}

Default Billing Strategy

This billing strategy will be the default to be assigned to new customers. It could also have been named Net 15.

Listing 1.3 – DefaultBillingStrategy.cs
public class DefaultBillingStrategy : BillingStrategy
{
    public override DateTime GetDueDate()
    {
        DateTime dueDate = DateTime.Now.AddDays(15).Date;

        return dueDate;
    }
}

Net 30 Billing Strategy

This billing strategy allows 30 days for payment.

Listing 1.4 – Net30BillingStrategy.cs
public class Net30BillingStrategy : DefaultBillingStrategy
{
    public override DateTime GetDueDate()
    {
        DateTime dueDate = DateTime.Now.AddDays(30).Date;

        return dueDate;
    }
}

Customer

The customer is a simple object to hold the name and address values as well as the BillingStrategy object.

Listing 1.5 – Customer.cs
public class Customer
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string StreetAddress { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string PostalCode { get; set; }
    public BillingStrategy Strategy { get; set; }

}

Implementation

The implementation is rather simple if you look past the customer creation code.

Listing 1.6 – Implementation
List<Customer> customers = new List<Customer>();

customers.Add(new Customer
{
    City = "San Francisco",
    ID = 1,
    Name = "Digital Monikors",
    PostalCode = "94122",
    State = "CA",
    Strategy = new DefaultBillingStrategy(),
    StreetAddress = "100 W Main St"
});

customers.Add(new Customer
{
    City = "New York",
    ID = 2,
    Name = "Broadway Partners",
    PostalCode = "10001",
    State = "NY",
    Strategy = new Net30BillingStrategy(),
    StreetAddress = "100 E Main St"
});

customers.Add(new Customer
{
    City = "Denver",
    ID = 3,
    Name = "Mile High Design",
    PostalCode = "80201",
    State = "CO",
    Strategy = new DefaultBillingStrategy(),
    StreetAddress = "100 Main St"
});

foreach(Customer customer in customers)
{
    string[] address = new string[2];
    address[0] = customer.Name;
    address[1] = $"{customer.City}, {customer.State} {customer.PostalCode}";

    customer.Strategy.SendBill(address);
}


Console.ReadKey();

Conclusion

If you are an experienced programmer, you may have already used the Strategy design pattern in your work and possibly not known what it was called. It is a very common pattern and one of the easiest to implement.

Leave a Reply

Your email address will not be published.