Hello guys, you might have heard about it, Can you tell me any design pattern which you have used recently in your project, except Singleton? This is one of the popular questions from various Java interviews in recent years. I think this actually motivated many Java programmers to explore more design patterns and actually look at the original 23 patterns introduced by GOF. The Strategy design pattern is one of the useful patterns you can mention while answering such a question. It's very popular, and there are lots of real-world scenarios where the Strategy pattern is very handy.
Many programmers ask me what the best way to learn design patterns is, I say you first need to find how other people use them and for that, you need to look at the open-source libraries you use in your daily task. JDK API is one such library I use on a daily basis, and that's why when I explore new algorithms, design patterns, I first search JDK for their usage.
The strategy pattern has found its place in JDK, and you know what I mean if you have sorted ArrayList in Java. Yes, a combination of the Comparator, Comparable, and the Collections.sort() method is one of the best real-world examples of the Strategy design pattern.
To understand it more, let's first find out what a Strategy pattern is? The first clue is the name itself. The strategy pattern defines a family of related algorithms l sorting algorithms like the bubble sort, quicksort, insertion sort and merge sort, or compression algorithm like zip, gzip, tar, jar, encryption algorithm like MD 5, AES, etc and lets the algorithm vary independently from clients that use it.
For example, you can use the Strategy pattern to implement a method that sorts numbers and allows the client to choose any sorting algorithm at runtime, without modifying the client's code. So essentially Strategy pattern provides flexibility, extensibility, and choice. You should consider using this pattern when you need to select an algorithm at runtime.
In Java, a strategy is usually implemented by creating a hierarchy of classes that extend from a base interface known as Strategy. In this tutorial, we will learn some interesting things about the Strategy pattern by writing a Java program and demonstrating how it adds value to your code.
And, If you are serious about learning design patterns and principles, I suggest you take a look at these best Design Patterns in Java courses on Udemy. This course covers both SOLID design principles like Open Closed and Liskov substitution, and all-important Object Oriented design patterns like Decorator, Observer, Chain of Responsibility, and much more
To understand it more, let's first find out what a Strategy pattern is? The first clue is the name itself. The strategy pattern defines a family of related algorithms l sorting algorithms like the bubble sort, quicksort, insertion sort and merge sort, or compression algorithm like zip, gzip, tar, jar, encryption algorithm like MD 5, AES, etc and lets the algorithm vary independently from clients that use it.
For example, you can use the Strategy pattern to implement a method that sorts numbers and allows the client to choose any sorting algorithm at runtime, without modifying the client's code. So essentially Strategy pattern provides flexibility, extensibility, and choice. You should consider using this pattern when you need to select an algorithm at runtime.
In Java, a strategy is usually implemented by creating a hierarchy of classes that extend from a base interface known as Strategy. In this tutorial, we will learn some interesting things about the Strategy pattern by writing a Java program and demonstrating how it adds value to your code.
And, If you are serious about learning design patterns and principles, I suggest you take a look at these best Design Patterns in Java courses on Udemy. This course covers both SOLID design principles like Open Closed and Liskov substitution, and all-important Object Oriented design patterns like Decorator, Observer, Chain of Responsibility, and much more
Ultimate Guide of Strategy Design Pattern in Java
Now, let's go through the Strategy design pattern in depth. I have covered things like what is Strategy Design pattern is, what benefit it offers, where to use a Strategy pattern, as well how to implement a Strategy design pattern in Java.You will also see some real-world examples of Strategy design patterns, particularly from JDK and other popular open-source libraries to understand the intent of Strategy design pattern in depth. After going through this article, you should be confident in using Strategy design patterns in your own Java projects and programs.
1. What is the Intent of the Strategy Design Pattern?
While learning a new pattern, the most important thing to understand is intent, motivation. Why? because two design patterns can have the same structure but their intent could be totally different. Even, one of good example of this theory is State and Strategy pattern.
If you look at the UML diagram of these two patterns they look identical but the intent of the State pattern is to facilitate state transition while the intent of the Strategy pattern is to change the behavior of a class by changing the internal algorithm at runtime without modifying the class itself. That's why the Strategy pattern is part of behavioral patterns in GOF's original list.
You can correlate the Strategy pattern with how people use a different strategy to deal with a different situation, for example, if you are confronted with a situation then you will either deal with it or run away with two different strategies.
If you have not read it already then you should also join Design Patterns in Java to learn the modern implementation of classic Java patterns. This is one of the best courses to learn the practical use of design patterns in Java applications.
If you look at the UML diagram of these two patterns they look identical but the intent of the State pattern is to facilitate state transition while the intent of the Strategy pattern is to change the behavior of a class by changing the internal algorithm at runtime without modifying the class itself. That's why the Strategy pattern is part of behavioral patterns in GOF's original list.
You can correlate the Strategy pattern with how people use a different strategy to deal with a different situation, for example, if you are confronted with a situation then you will either deal with it or run away with two different strategies.
If you have not read it already then you should also join Design Patterns in Java to learn the modern implementation of classic Java patterns. This is one of the best courses to learn the practical use of design patterns in Java applications.
2. Terminology and Structure of the Strategy Pattern
This pattern has two main components, Strategy interface, and Context class. Strategy interface declares the type of algorithm, it can be an abstract class or interface. For example, you can define a Strategy interface with method move(), now this move becomes strategy and different pieces in a game of chess can implement this method to define their moving strategy.For example, Rook will move only horizontal or vertical, Bishop will move diagonally, Pawn will move one cell at a time and Queen can move horizontal, vertical, and diagonally. The different strategy employed by different pieces for movement is an implementation of Strategy interface and the code which moves pieces is our Context class.
When we change the piece, we don't need to change the Context class. If a new piece is added, then also your code which takes care of moving pieces will not require to be modified.
You can further see the Software Design Patterns: Best Practices for Software Developers course on Educative to learn more about GOF design patterns. This is an interactive design pattern course where you will code in the browser to learn and understand design patterns.
Here is the UML diagram of the Strategy pattern :
Here is the UML diagram of the Strategy pattern :
3. Pros and Cons of Strategy Pattern
Every algorithm or pattern has some advantages and disadvantages and this pattern is also no different. The main benefit of using the Strategy pattern is flexibility. The client can choose any algorithm at run time, you can easily add a new Strategy without modifying classes that use strategies like Context.This becomes possible because the Strategy pattern is based upon the Open Closed design principle, which says that new behavior is added by writing a new code not by modifying the tried and tested old code.
If you use the Strategy pattern, you will be adding a new Strategy by writing a new class that just needs to implement the Strategy interface. Because of the open-closed principle violation, we cannot use Enum to implement the Strategy pattern.
Though it has some advantages and suits well if you know major algorithms well in advance you need to modify your Enum class to add new algorithms which is a violation of the open-closed principle. To learn more see here.
If you use the Strategy pattern, you will be adding a new Strategy by writing a new class that just needs to implement the Strategy interface. Because of the open-closed principle violation, we cannot use Enum to implement the Strategy pattern.
Though it has some advantages and suits well if you know major algorithms well in advance you need to modify your Enum class to add new algorithms which is a violation of the open-closed principle. To learn more see here.
4. Real-World Examples of Strategy Design Pattern
JDK has a couple of examples of this pattern, the first is Collection.sort(List, Comparator) method, where Comparator is Strategy and Collections.sort() is Context. Because of this pattern, your sort method can sort any object, the object which doesn't exist when this method was written.As long as, Object will implement the Comparator interface (Strategy interface), the Collections.sort() method will sort it.
Another example is java.util.Arrays#sort(T[], Comparator < ? super T > c) method which similar to Collections.sort() method, except need array in place of List.
You can also see the classic Head First Design pattern book for more real-world examples of Strategy and other GOF patterns. Most of my knowledge of GOF design patterns is attributed to this book. It's been 10 years since the book was first released, thankfully it is now updated to cover Java SE 8 as well.
Another example is java.util.Arrays#sort(T[], Comparator < ? super T > c) method which similar to Collections.sort() method, except need array in place of List.
You can also see the classic Head First Design pattern book for more real-world examples of Strategy and other GOF patterns. Most of my knowledge of GOF design patterns is attributed to this book. It's been 10 years since the book was first released, thankfully it is now updated to cover Java SE 8 as well.
5. Strategy Pattern Implementation in Java
Here is a simple Java program that implements a Strategy design pattern. You can use this sample code to learn and experiment with this pattern. The example is very simple, all it does is define a strategy interface for sorting algorithms and use that interface on a method called arrange.This method can arrange objects in increasing or decreasing order, depending upon how you implement them. In order to arrange an object, you need sorting and this is provided by a Strategy pattern. This allows you to choose any algorithm to sort your object.
/** * Java Program to implement Strategy design pattern in Java. * Strategy pattern allows you to supply different strategy without * changing the Context class, which uses that strategy. You can * also introduce new sorting strategy any time. Similar example * is Collections.sort() method, which accept Comparator or Comparable * which is actually a Strategy to compare objects in Java. * * @author WINDOWS 8 */ public class Test { public static void main(String args[]) throws InterruptedException { // we can provide any strategy to do the sorting int[] var = {1, 2, 3, 4, 5 }; Context ctx = new Context(new BubbleSort()); ctx.arrange(var); // we can change the strategy without changing Context class ctx = new Context(new QuickSort()); ctx.arrange(var); } } interface Strategy { public void sort(int[] numbers); } class BubbleSort implements Strategy { @Override public void sort(int[] numbers) { System.out.println("sorting array using bubble sort strategy"); } } class InsertionSort implements Strategy { @Override public void sort(int[] numbers) { System.out.println("sorting array using insertion sort strategy"); } } class QuickSort implements Strategy { @Override public void sort(int[] numbers) { System.out.println("sorting array using quick sort strategy"); } } class MergeSort implements Strategy { @Override public void sort(int[] numbers) { System.out.println("sorting array using merge sort strategy"); } } class Context { private final Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void arrange(int[] input) { strategy.sort(input); } } Output sorting array using bubble sort strategy sorting array using quick sort strategy
6. Things to Remember about Strategy Pattern in Java
Now let's revise what you have learned in this tutorial about the strategy design pattern :1) This pattern defines a set of related algorithm and encapsulate them in separated classes, and allows the client to choose any algorithm at run time.
2) It allows adding a new algorithm without modifying existing algorithms or context class, which uses algorithms or strategies.
3) The strategy is a behavioral pattern in the GOF list.
4) The strategy pattern is based upon the Open Closed design principle of SOLID Principles of Object-Oriented Design.
5) The Collections.sort() and Comparator interface is a real-world example of the Strategy pattern.
That's all about how to implement the Strategy pattern in Java. For your practice write a Java program to implement encoding and allow the client to choose between different encoding algorithms like base 64. This pattern is also very useful when you have a situation where you need to behave differently depending upon type like writing a method to process trades if trades are of type NEW, it will be processed differently, if it is CANCEL then it will be processed differently and if its AMEND then also it will be handled differently, but remember each time we need to process trade.
Other Java Design Patterns tutorials you may like
- Top 5 Courses to learn Design Pattern in Java (courses)
- 5 Free Courses to learn Object Oriented Programming (courses)
- Difference between Factory and Dependency Injection Pattern? (answer)
- Top 5 Courses to learn Microservices in Java with Spring (courses)
- How to create thread-safe Singleton in Java? (example)
- How to implement the Strategy Design Pattern in Java? (example)
- Difference between Factory and Abstract Factory Pattern? (example)
- 18 Java Design Pattern Interview Questions with Answers (list)
- How to design a Vending Machine in Java? (questions)
- 20 System Design Interview Questions (list)
- Difference between State and Strategy Design Pattern in Java? (answer)
- Top 5 Courses to learn Design Patterns in Java (courses)
- 5 Free Courses to learn Data Structure and Algorithms (courses)
- My favorite courses to learn Software Architecture (courses)
Thanks for reading this article so far. If you like this strategy design pattern tutorial then please share them with your friends and colleagues. If you have any questions or feedback then please drop a note.
P. S. - If you are looking for some free courses to learn Design Pattern and Software Architecture, I also suggest you check out these free Java Design Patterns and Architecture courses by John Purcell on Udemy. It's completely free, all you need to do is create an Udemy account to access this course.
Strategy is my favorite pattern and we keep finding it usages everywhere. Couple of days back, I have to code discount rates based upon COUPON type, and guess what? I used Strategy pattern. It make it very easy to introduce a new coupon type with a differnet discounted rate without modifying billing engine code.
ReplyDeleteCan you please explain some drawbacks of Strategy pattern? This was asked to me on recent interview and I only manage to tell that it require lot of classes .... Interviewer not very impressed.
ReplyDelete"Because of open closed principle violation, we cannot use Enum to implement Strategy pattern. Though it has some advantage and suits well if you know major algorithm well in advance but you need to modify your Enum class to add new algorithms which is violation of open closed principle."
ReplyDeleteWhy would it be a problem to add an entry into an Enum as we have to rebuild the whole module/project to add the new implementation of the Strategy interface, and very often also add some user description of the new algorithm (so that a user can choose this strategy instead of another) ?
can you please explain the command pattern
ReplyDeleteThere is slight wrong implementation. In diagram, you showed context implements Strategy interface, while in the coding you have used a different method 'arrange'.
ReplyDeleteHello Anonymous, context doesn't implement Strategy, it actually holds a reference to Strategy interface to perform the task.
Delete