Strategy Pattern in Java with Example

Strategy 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 pattern is, I say you first need to find how other people use it 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 ComparatorComparable, and Collections.sort() method are one of the best real-world examples of the Strategy design pattern.

To understand it more, let's first find out what Strategy pattern is? The first clue is the name itself.  The strategy pattern defines a family of related algorithms l sorting algorithms like bubble sortquicksortinsertion sort and merge sort, or compression algorithm e.g. zip, gzip, tar, jar, encryption algorithm e.g. MD 5, AES etc and lets the algorithm vary independently from clients that use it.

For example, you can use Strategy pattern to implement a method which sort numbers and allows the client to choose any sorting algorithm at runtime, without modifying client's code. So essentially Strategy pattern provides flexibility, extensible 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 Strategy pattern by writing a Java program and demonstrating how it add value to your code. See Head First design pattern for more details on this and other GOF patterns. This book is also updated to Java SE 8 on its 10th anniversary.




What is the Intent of Strategy Design Pattern?

While learning a new pattern, most important thing to understand is intent, motivation. Why? because two design pattern can have the same structure but their intent could be totally different. Even, one of a good example of this theory is State and Strategy pattern.

If you look at UML diagram of these two patterns they look identical but the intent of State pattern is to facilitate state transition while the intent of Strategy pattern is to change the behavior of a class by changing internal algorithm at runtime without modifying the class itself.  That's why Strategy pattern is part of behavioral patterns in GOF's original list.

You can correlate 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 two different strategies.

If you have not read already then you should also read the Head First Design pattern, one of the best books to learn practical use of design pattern in Java application. Most of my knowledge of GOF design patterns are 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.





Terminology and Structure of the Strategy Pattern

This pattern has two main component, Strategy interface, and Context class. Strategy interface declares the type of algorithm, it can be 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 are an implementation of Strategy interface and the code which moves pieces is our Context class.

When we change piece, we don't need to change Context class. If a new piece is added, then also your code which takes care of moving pieces will not require to be modified.

Here is UML diagram of Strategy pattern :
Strategy Design Pattern Implementation in Java



Pros and Cons of Strategy Pattern

Every algorithm or pattern has some advantage and disadvantage 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 new Strategy without modifying classes which use strategies e.g. Context. This becomes possible because the Strategy pattern is based upon Open Closed design principle, which says that new behavior is added by writing 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 advantage 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 open-closed principle. To learn more see here.


Real-World Examples of Strategy Design Pattern

JDK has a couple of examples of this pattern, 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), 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.


Strategy Pattern Implementation in Java

Here is a simple Java program which 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. 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




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) Collections.sort() and Comparator interface is a real-world example of the Strategy pattern.

SHARE

esant technology

0 comments :

Post a Comment