The Strategy pattern in C# lets the algorithm vary independently from clients that use it.
There may be different algorithms (strategies) that apply to a given problem. If the algorithms are all kept in the client, messy code with lots of conditional statements will result.
Strategy pattern defines a family of algorithms, encapsulate each one, and make them interchangeable.
The Strategy pattern enables a client to choose which algorithm to use from a family of algorithms and gives it a simple way to access it.
Below is the UML and sequence diagram of Strategy pattern from Wikipedia.
Strategy Pattern C# Example
Strategy Pattern Using Context Class
Let’s start with the problem statement,
Now, In our imaginary store we 25% discount on price of item for the months of July-December. And, we do not provide any discount for the months of Jan-June.
Let’s see how this fit in strategy pattern,
Here we declared two strategies, NoDiscountStrategy and QuarterDiscountStrategy, as per problem statement.
Let’s continue with the example and implement the context,
In strategy pattern context is optional. But if it is present, it acts as single point of contact for client.
Now, we can implement the client code,
Above example shows the usage of Strategy pattern with Context. Context can be used as single point of contact for the Client.
As shown in the output below, you will get discount depending on the month you have entered.
Multiple uses of Context
It can populate data to execute an operation of strategy
It can take independent decision on Strategy creation.
In absence of Context, client should be aware of concrete strategies. Context acts a
wrapper and hides internals
Code re-factoring will become easy
Strategy Pattern Without Using A Context Class
The following is a simple example of using the strategy pattern without a context class.
Here we have two implementation strategies which implement the interface and solve the same problem in different ways.
Users of the EnglishTranslation class can call the translate method and choose which strategy they would like to use for the translation, by specifying the desired strategy.
Strategy Pattern Using Service Class
The purpose of this example is to show how we can implement Strategy pattern using a Service Class.
The example problem we using is a family of algorithms (strategies) that describe different ways to communicate over a distance.
The contract for our family of algorithms is defined by the following interface:
Then we can implement a number of algorithms, as follows:
These can be instantiated as follows:
Next, we implement a service that uses the strategy:
Finally, we can use the different strategies as follows:
Strategy Pattern Using C# Delegates
The contract of the different algorithm implementations does not need a dedicated interface.
The different algorithms composing the family of algorithms can be expressed as lambda
expressions. This replaces the strategy classes and their instantiations.
Next, we can code the “service” as follows:
Finally we use the strategies as follows:
Or even:
Note: You can download the complete solution demo from my github repository.
Where To Apply Strategy Pattern?
When many related classes differ only in their behavior. Strategies provide a
way to configure a class with one of many behaviors.
You need different variants of an algorithm. For example, you might
define algorithms reflecting different space/time trade-offs. Strategies
can be used when these variants are implemented as a class hierarchy of
algorithms.
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 Strategy class.
Applying The Strategy Pattern To Vary Data Access Methods In C# by Carl Layton - In this post, Carl explains how a data access layer can make good use of the strategy pattern because it can abstract out the implementation of the actual data access mechanism from the consumer of the data access layer.
Subscribe to Code with Shadman
Get the latest posts delivered right to your inbox