This is useful if one class needs to do something, but there are multiple ways of doing that thing - think sorting algorithms, searching algorithms or layout managers.
Each "strategy" of doing it must have a common access method, abstracted away by an interface. As long as it correctly implements that interface, it is a valid strategy. My example will be for search algorithms through an array, so my interface will look as follows:
strategy.Searcher
package strategy;
public interface Searcher {
public int search(int[] arr, int val) throws ItemNotFoundException;
}
You can then see I used an exception, so I have to create that as a class
strategy.ItemNotFoundException
package strategy;
public class ItemNotFoundException extends Exception {
}
From there I can write code that uses this abstract strategy to search for something.
Main
import strategy.*;
public class Main {
static Searcher searchAlgorithm = new BinarySearch();
public static void main(String[] args) {
int[] arr = {1,3,5,8,10,12,16,18};
int toSearch = 8;
System.out.print("Searching array [");
for(int i = 0; i < arr.length; i++) {
System.out.print("" + arr[i] + ",");
}
System.out.println("For item " + toSearch);
try {
int result = searchAlgorithm.search(arr, toSearch);
System.out.println("Item found at index " + result);
} catch (ItemNotFoundException e) {
System.out.println("Item not found");
}
}
}
And then I can implement multiple of those search algorithms
strategy.LinearSearch
package strategy;
public class LinearSearch implements Searcher {
public int search(int[] arr, int val) throws ItemNotFoundException {
for(int i = 0; i < arr.length; i++) {
if(arr[i] == val) {
return i;
}
}
throw new ItemNotFoundException();
}
}
strategy.BinarySearch
package strategy;
public class BinarySearch implements Searcher {
public int search(int[] arr, int val) throws ItemNotFoundException {
int l = 0;
int r = arr.length - 1;
while(l <= r) {
int m = (l + r) / 2;
if(arr[m] < val)
l = m + 1;
else if (arr[m] > val)
r = m - 1;
else
return m;
}
throw new ItemNotFoundException();
}
}
And you have just implemented the strategy pattern! The strategy used can be changed at runtime, simply by chaging the searchAlgorithm
function between the two strategy classes.