Meet our first design pattern super Hero - Mr. Strategy!!
![]() |
Mr. Strategy is our design pattern superhero this week!!! |
Definition: Strategy pattern defines a family of algorithms, encapsulates each one and
Given below is the UML representation of Mr.Strategy's modus operandi:

The following are the important players involved in Mr.Strategy's strategy to defeat the evil guys
Context
This refers to the class that will contain the base Strategy Interface which in our case is "IStrategy". The Context would know only about "IStartegy" and will not know about the classes implementing the IStartegy interface. It is also possible to have a parent class instead of the interface. Choose a class if you need a default implementation that all child classes should implement.Through the "Strategy" property, it would be possible to vary the Strategy type used by the context at runtime.
IStrategy
This defines the "operation" or the algorithm that varies for every class that implements this interface. This in our case is the "DoOperation()" method.
ConcreteStrategy_1 && ConcreteStrategy_2
This classes are the implementations of the IStrategy interface. These would be instantiated and assigned to the Context class by another Class(This can be a Factory/Control class). As you can see, it is possible to vary the algorithm used by the Context class for the "DoOperation()" method independent from the Context class. Moreover this can be done at run time instead of compile time.
Case Study
Okay to understand this better consider the following implementation of a method "CalculateShippingCost(): in a Cart class. The class diagram is shown below:

The code for the CalculateShippingCost() Method is shown below
|
public double CalculateShippingCost(string country) |
Now here are some problems with this implementation
|
When Mr.Strategy applies his powers to the above example, the class diagram now becomes

Here are our main players that map with the original players in the Strategy definition
| Context | ShoppingCart |
| Strategy | IShippingStrategy |
| Concrete Implementations | UsaShippingStrategy, CanadaShippingStrategy |
| Client setting the Strategy | WebApplication |
As we can see, someone has to take the property of setting the appropriate "shipping strategy " in the Shopping cart class. In our example it is the "Web Application". One of the drawback/feature of applying the Strategy pattern is the need of some class to know about the different strategies and set them in the Context class.
The code for CalculateShippingCost in ShoppingCart now looks like
|
public double CalculateShippingCost() |
And the Shipping Strategy is now set by the Web Application. The example below uses a switch statement, but it is possible to read this from a configuration file also.
| public void UpdateShipping(string countrySelected) { switch (countrySelected) { case ("USA"): { shoppingCart.ShippingStrategy = this.usaShippingStrategy; break; } case ("Canada"): { shoppingCart.ShippingStrategy = this.canadaShippingStrategy; break; } } } |
Advantages of using services of Mr.Strategy
So what have we gained ?
|
Refactoring to the strategy pattern
You can also refactor existing code to the STrategy pattern to make it more easy to maintain and extend. Martin Fowler and Joshua KereieVsky suggest using this pattern for resolving a code smell called "Switch Statement". This refers to a piece of code that has a lot of conditional logic (in the form of switch/if statements)
Note: If you have a large no of case statements (like 200 case statements) that just returns a literal value based on the switch value compared, you are better of using a table driven approach. You can load all the values and the keys (the value that you pass in the switch statement) in a hash table. This will reduce lookup time and increase performance !
Real World Examples
The IComparer strategy defined in System.Collections namespace provides the way the objects in a collection have to be sorted. The algorithm that can be implemented by the objects go into the "Compare()" method. The definition of the compare method is given below
public int Compare(object x, object y);
It is possible for you to provide concrete implementations of this strategy, like ProductComparer that would have the following implementation that compares and sorts products based on their product Name.
| class ProductComparer : IComparer { public int Compare(object firstProduct, object secondProduct) { Product product1 = firstProduct as Product; Product product2 = secondProduct as Product; return product1.Name.CompareTo(product2.Name); } } |
And if you had an ArrayList called "productsCollection" containing Product objects, you can sort them as follows
productsCollection.Sort(new ProductComparer());
Mr.Startegy's Relatives
These include : Mr.State and Ms. Template Method
Okay, that covers up this weeks discussion about our superhero
Next week we will cover our second superhero of the week --> Ms. Decorator



Comments