Strategy Design Pattern

Another day, another Design Pattern, in this article I will explain the Strategy Design Pattern.

The Strategy pattern allows you to define an algorithm separately and select the algorithm dynamically at run time. This pattern defines a set of algorithms, encapsulates each one of them and makes them interchangeable. It allows the algorithm to vary independently of the clients that use it.

Participants

strategyDesignPattern_1

The classes and objects that participate in this model are:

Strategy
Declare a common interface for all supported algorithms. Context uses this interface to call the algorithm defined by a ConcreteStrategy

ConcreteStrategy
Implement the algorithm using the Strategy interface

Context
It is configured with a ConcreteStrategy object
Maintains a reference to a Strategy object
You can define an interface that allows you to access your Strategy data.

When to use it

There are common situations when classes differ only in their behaviour. For this case, it is a good idea to isolate the algorithms in separate classes in order to have the ability to select different algorithms at runtime. The Strategy pattern allows us to provide an alternative to subclassing the Context class to get a variety of algorithms or behaviours, eliminates large conditional statements and provides a choice of implementations for the same behaviour.

Use the Strategy pattern whenever:

  • Many related classes differ only in their behaviour
  • You need different variants of an algorithm
  • An algorithm uses data that clients shouldn’t know about. Use the Strategy pattern to avoid exposing complex, algorithm-specific data structures.
  • A class defines many behaviors, and these appear as multiple conditional statements in its operations. Instead of many conditionals, move related conditional branches into their own Strategy class.

Demo

We’ll simulate a simple fee calculation application based on the type of payment of an order, where the calculation will depend on the type of the payment: Paypal or Creditcard.

  1. Strategy

We define the Strategy Interface from which the other strategies will be implemented.

public interface IPaymentStrategy
    {
        double CalculateFee();
    }

2. Concrete Strategy

We define the concrete strategies that encapsulate our behavioral algorithm

public class PaypalStrategy : IPaymentStrategy
    {
        public double CalculateFee()
        {
            return 2.00d;
        }
    }

public class CreditCardStrategy : IPaymentStrategy
    {
        public double CalculateFee()
        {
            return 3d;
        }
    }

3. Create the Domain class Order

public class Order
    {
        public int Id { get; set; }
        public string Address { get; set; }
        public IPaymentStrategy PaymentOption { get; set; }
    }

4. Context

We define our Context class, where we will pass the strategies

public class FeeCalculationService
    {
        private readonly IPaymentStrategy _paymentStrategy;

        public FeeCalculationService(IPaymentStrategy paymentStrategy)
        {
            _paymentStrategy = paymentStrategy;
        }

        public double CalculateFeeBasedOnPaymentOption()
        {
            return _paymentStrategy.CalculateFee();
        }
    }

5. Client

class Program
    {
        static void Main(string[] args)
        {
            //create order
            var order = new Order()
            {
                Id = 1,
                Address = "Dublin, Ireland",
                PaymentOption = new PaypalStrategy()
            };

            var feeCalculationService = new FeeCalculationService(order.PaymentOption);
            var fee = feeCalculationService.CalculateFeeBasedOnPaymentOption();

            Console.WriteLine("Calculated fee: " + fee);
            Console.ReadKey();

        }
    }

Using this pattern we will be fulfilling two principles of SOLID that are: Single Responsibility Principle and the Open/Closed principle, which will help us a lot when we want to extend and / or add new functionalities to our classes without major headaches

You can find the code of the Demo in my Github

References

Design patterns and practices in .NET: the Strategy Pattern
https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm
http://www.oodesign.com/strategy-pattern.html

Advertisements
This entry was posted in Architecture and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s