# Strategy Design Pattern explained in 2 minutes

### Problem Statement

If you want to dynamically make decisions in your class based on certain actions, then what’s the best way to achieve this?

```java
public class OrderedList<T> {
    List<T> list;
  
    public OrderedList(List<T> list) {
        this.list = list;
    }

    public List<T> sort(String algo) {
        if ("bubble".equals(algo)) {
            return bubbleSort(list);
        } else if ("merge".equals(algo)) {
            return mergeSort(list);
        } else {
            throw new RuntimeException("Unsupported algo " + algo);
        }
    }
}
```

In the above code, if you need to change the sorting strategy based on the function argument, then the simplest way would be to use `if/else` and do a dispatch to the correct method body based on the argument.

Why would this be a problem?

Because, in the future, if you need to add a new strategy, you would have to update this class - which would violate the OCP (Open/Closed Principle) of the SOLID principle.

### Solution?

```java
public class OrderedList<T> {
    List<T> list;
    SortingStrategy<T> strategy;
    public OrderedList(List<T> list, SortingStrategy<T> strategy) {
        this.list = list;
        this.strategy = strategy;
    }

    // You can also update the code to take in Strategy at the time of sorting itself
    public List<T> sort() {
        return strategy.execute(list);
    }
}

public interface SortingStrategy<T> {
    List<T> execute(List<T> list);
}

public class MergeSort<T> implements SortingStrategy<T> {
    @Override
    public List<T> execute(List<T> list) {
        System.out.println("Performing merge sort");
        return list;
    }
}

public class BubbleSort<T> implements SortingStrategy<T> {
    @Override
    public List<T> execute(List<T> list) {
        System.out.println("Performing bubble sort");
        return list;
    }
}

public class Main {
    public static void main(String[] args) {
        testStrategy();
    }

    public static void testStrategy() {
        List<Integer> list = Arrays.asList(1, 2, 3, 4);
        BubbleSort<Integer> bubbleSort = new BubbleSort<>();
        MergeSort<Integer> mergeSort = new MergeSort<>();
        OrderedList<Integer> orderedList1 = new OrderedList<>(list, bubbleSort);
        orderedList1.sort();
        OrderedList<Integer> orderedList2 = new OrderedList<>(list, mergeSort);
        orderedList2.sort();
    }
}
// Output
Performing bubble sort
Performing merge sort
```

Using the strategy pattern, you can create new strategies and update the behavior of the class without modifying the class!

### What's the benefit?

* Follows the OCP principle - class should be open for extension but closed for modification. You can change the behavior of the class by injecting a new strategy at runtime.
    
* Follows the SRP (Single Responsibility Principle) - class should have only one responsibility. Only one strategy is present in one class.
    
* Follows the `Composition over Inheritance` principle suggested by GoF (Gang Of Four).
    

### What's the drawback?

* Creating new classes every time can create clutter if not done judiciously. Many languages allow you to create anonymous classes e.g. lambdas in Java - which can reduce the boilerplate code creation.
