As always we will learn this pattern by defining a problem and using strategy pattern to solve it. Suppose we are building a game “Street Fighter”. For simplicity assume that a character may have four moves that is kick, punch, roll and jump. Every character has kick and punch moves, but roll and jump are optional. How would you model your classes? Suppose initially you use inheritance and abstract out the common features in a Fighter class and let other characters subclass Fighter class.
Fighter class will we have default implementation of normal actions. Any character with specialized move can override that action in its subclass. Class diagram would be as follows:
What are the problems with above design?
What if a character doesn’t perform jump move? It still inherits the jump behavior from superclass. Although you can override jump to do nothing in that case but you may have to do so for many existing classes and take care of that for future classes too. This would also make maintenance difficult. So we can’t use inheritance here.
What about an Interface?
Take a look at the following design:
It’s much cleaner. We took out some actions (which some characters might not perform) out of Fighterclass and made interfaces for them. That way only characters that are supposed to jump will implement the JumpBehavior.
What are the problems with above design?
The main problem with the above design is code reuse. Since there is no default implementation of jump and roll behavior we may have code duplicity. You may have to rewrite the same jump behavior over and over in many subclasses.
How can we avoid this?
What if we made JumpBehavior and RollBehavior classes instead of interface? Well then we would have to use multiple inheritance that is not supported in many languages due to many problems associated with it.
Here strategy pattern comes to our rescue. We will learn what the strategy pattern is and then apply it to solve our problem.
Wikipedia defines strategy pattern as:
“In computer programming, the strategy pattern (also known as the policy pattern) is a software design pattern that enables an algorithm’s behavior to be selected at runtime. The strategy pattern
- defines a family of algorithms,
- encapsulates each algorithm, and
- makes the algorithms interchangeable within that family.”
Here we rely on composition instead of inheritance for reuse. Context is composed of a Strategy. Instead of implementing a behavior the Context delegates it to Strategy. The context would be the class that would require changing behaviors. We can change behavior dynamically. Strategy is implemented as interface so that we can change behavior without affecting our context.
We will have a clearer understanding of strategy pattern when we will use it to solve our problem.
- A family of algorithms can be defined as a class hierarchy and can be used interchangeably to alter application behavior without changing its architecture.
- By encapsulating the algorithm separately, new algorithms complying with the same interface can be easily introduced.
- The application can switch strategies at run-time.
- Strategy enables the clients to choose the required algorithm, without using a “switch” statement or a series of “if-else” statements.
- Data structures used for implementing the algorithm are completely encapsulated in Strategy classes. Therefore, the implementation of an algorithm can be changed without affecting the Context class.
- The application must be aware of all the strategies to select the right one for the right situation.
- Context and the Strategy classes normally communicate through the interface specified by the abstract Strategy base class. Strategy base class must expose interface for all the required behaviours, which some concrete Strategy classes might not implement.
- In most cases, the application configures the Context with the required Strategy object. Therefore, the application needs to create and maintain two objects in place of one.
- Head First Design Patterns
This article is contributed by Sulabh Kumar. If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to email@example.com. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above