Summary: This tutorial provides a discussion of the Strategy Design Pattern using Java source code examples.
The Strategy Design Pattern consists of a number of related algorithms encapsulated in a driver class often named Context. A user or a client program typically selects the algorithm they want to use, although the Context class may also select the algorithm automatically.
The intent of the Strategy Pattern is to make the algorithms easily interchangeable, and provide a means to choose the appropriate algorithm at a particular time.
Here is a brief summary of the Strategy Design Pattern:
- Algorithms (strategies) are chosen at runtime.
- A Strategy is dynamically selected by a client (a user or consuming program), or by the Context.
- Your driver/controller class is typically named Context, though there is no requirement for this.
- The Context class is aware of a variety of different algorithms, and each algorithm is considered a Strategy, and the name Strategy is often used as part of each class name, although again, this is only convention, and not a requirement.
- The Context class is responsible for handling the data during the interaction with the client.
Examples of the Strategy Design Pattern
Here are several Strategy Design Pattern examples from the Design Patterns Smalltalk Companion:
- Saving files in different formats.
- Word, ODT, RTF, HTML plain text.
- Excel, CSV, HTML.
- Compress files using different compression algorithms.
- Capture video using different video compression algorithms.
- Plot the same data using different formats (points, line chart, bar chart, etc.)
From Wiley’s Patterns in Java:
- Display calendars, with different holidays for different countries. (Strategy classes are USAHoliday, CanadaHoliday, etc.)
From Larman’s Applying UML and Patterns:
- A store may have various pricing strategies (10% off everything, $10 off when the total exceeds $200, etc.), and these strategies may be used at different times.
(From my own experience working with a pizza company, they wanted us to consider different pricing strategies like this at the same time, and choose the strategy that was best for the customer.)
A Java Strategy Design Pattern example
In an effort to demonstrate a Java Strategy Pattern example, I've created a modified version of the Java Strategy Pattern example on the Wikipedia website. I thought this would be good so you can see two example Java Strategy Pattern examples with a similar code base.
In the case of the Wikipedia example, I didn't like the way they were passing in new strategies to the Context class. I thought that could be misleading, as typically the consumer of the strategies doesn't do something like this. The consumer classes might typically tell the Context, “I want to use StrategyA” through a method call, as I show below.
/** * This example is a minor improvement of the Java Strategy Design Pattern example * shown on wikipedia at this url: * * http://en.wikipedia.org/wiki/Strategy_pattern */ public class JavaStrategyDesignPatternExample { // this is our "driver" method to demonstrate our // Java Strategy Design Pattern example public static void main(String[] args) { Context context; // a demonstration of how we might choose different strategies context = new Context(); context.setAddStrategy(); int resultA = context.executeStrategy(3, 4); context = new Context(); context.setMultiplyStrategy(); int resultB = context.executeStrategy(3, 4); context = new Context(); context.setSubtractStrategy(); int resultC = context.executeStrategy(3, 4); } } /** * The classes that implement a concrete strategy should implement this interface. */ interface Strategy { int execute(int a, int b); } /** * Configured with a ConcreteStrategy object and maintains a reference to a * Strategy object. */ class Context { // the Context doesn't know anything about concrete Strategy classes, it only knows // about the Strategy interface private Strategy strategy; public void setAddStrategy() { this.strategy = new ConcreteStrategyAdd(); } public void setMultiplyStrategy() { this.strategy = new ConcreteStrategyMultiply(); } public void setSubtractStrategy() { this.strategy = new ConcreteStrategySubtract(); } public int executeStrategy(int a, int b) { return strategy.execute(a, b); } } // Concrete Strategy class implementations shown below here. class ConcreteStrategyAdd implements Strategy { public int execute(int a, int b) { System.out.println("Called ConcreteStrategyAdd's execute()"); return a + b; // Do an addition with a and b } } class ConcreteStrategySubtract implements Strategy { public int execute(int a, int b) { System.out.println("Called ConcreteStrategySubtract's execute()"); return a - b; // Do a subtraction with a and b } } class ConcreteStrategyMultiply implements Strategy { public int execute(int a, int b) { System.out.println("Called ConcreteStrategyMultiply's execute()"); return a * b; // Do a multiplication with a and b } }
A good way to think about the Strategy Pattern is to think about a GUI application. When it comes to charts in Excel, there may be different buttons labeled:
- Line chart
- Bar chart
- Pie chart
Of if you think about an application like Word, it may have menu options like these:
- Save as Word '97
- Save as Word (XML)
- Save as RTF
- Save as HTML
- Save as Plain Text
In all of these examples, the user dynamically chooses which "strategy" they want to choose at runtime. These are all examples of the Strategy Pattern.
Now, if you think about the small Java Strategy Pattern example shown above, try to imagine the three concrete strategies being chosen by a user in a GUI application, and I think you'll understand the Strategy Design Pattern.
Related design patterns
Many design patterns appear to be similar or related to other design patterns. Here are some notes about the Strategy Design Pattern:
- The Strategy pattern is similar to the State Pattern, but different in their intent.
- The Adapter Pattern is structurally similar to the Strategy Pattern, but again, the difference is intent.
- The UML class diagram for the Bridge Pattern is the same, or essentially the same, as the UML class diagram for the Strategy Pattern. Again, the intent is different; Strategy is designed for behavior, and Bridge is meant for structure.
- I've heard the Template Method Design Pattern compared to Strategy, in that the Template Method provides alternate behaviors through subclassing, while the Strategy Pattern provides alternate behaviors through delegation.
- In their configuration, I've heard Strategy compared to the Factory Design Pattern. However, the Factory Design Pattern is a "Creational Pattern", while the Strategy Design Pattern is a "Behavioral Pattern".
(I'll cover all these in more detail once I write up examples of all the other design patterns in Java.)
The Strategy Design Pattern in Java
I hope this discussion of the Strategy Design Pattern in Java has been helpful. I'll continue to update this article as I think of new ideas and examples that may be helpful.