Compare hotel prices and find the best deal - HotelsCombined.com

Tuesday, January 6, 2015

Strategy Pattern in Java with Example

Strategy pattern is one of the useful pattern you can mention while answering such question. It's very popular and there are lots of real world scenario where Strategy pattern is very handy. Many programmer ask me what is the best way to learn design pattern, 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 daily basis and that's why when I explore new algorithms, design pattern, I first search JDK for their usage. Strategy has found its place in JDK, and you know what I mean if you have sorted ArrayList in Java. Yes, combination of ComparatorComparable andCollections.sort() method are one of the best real world example of Strategy design pattern. To understand it more, let's first find out what is Strategy pattern? First clue is in the name itself.  The strategy pattern defines a family of related algorithms e.g. sorting algorithms like bubble sort,quicksortinsertion 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 client to choose any sorting algorithm at run time, 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, 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.




What is Intent of Strategy Pattern

While learning a new pattern, most important thing to understand is intent, motivation. Why? because two design pattern can have same structure but their intent could be totally different. Even, one of the good example of this theory is State and Strategy pattern. If you look at UML diagram of these two pattern they look identical but intent of State pattern is to facilitate state transition while 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 different strategy to deal with different situation, for example if you are confronted with a situation then you will either deal with it or run away, two different strategy.


Terminology and Structure of 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.  Different strategy employed by different pieces for movement are 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 take care of moving pieces will not required 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. Main benefit of using Strategy pattern is flexibility. Client can choose any algorithm at run time, you can easily add new Strategy without modifying classes which uses strategies e.g. Context. This becomes possible because Strategy pattern is based upon Open Closed design principle, which says that new behavior is added by writing new code not by modifying tried and tested old code. If you use Strategy pattern, you will be adding a new Strategy by writing a new class which just need to implement Strategy interface. 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. To learn more see here.


Real World Examples of Strategy Design Pattern

JDK has 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 exists when this method was written. As long as, Object will implement 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.


Strategy Pattern Implementation in Java

Here is simple Java program which implements 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 object in increasing or decreasing order, depending upon how you implement. In order to arrange object, you need sorting and this is provided by 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 learn in this tutorial about strategy design pattern  :

1) This pattern defines a set of related algorithm and encapsulate them in separated classes, and allows client to choose any algorithm at run time.

2) It allows to add new algorithm without modifying existing algorithms or context class, which uses algorithm or strategies.

3) Strategy is a behavioral pattern in GOF list.

4) Strategy pattern is based upon Open Closed design principle of SOLID.

5) Collections.sort() and Comparator interface is real world example of Strategy pattern.


That's all about how to implement Strategy pattern in Java. For your practice write a Java program to implement encoding and allow client to choose between different encoding algorithm e.g. base 64. This pattern is also very useful when you have situation where you need to behave differently depending upon type e.g. writing a method to process trades, if trades is 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