Pizza flavoured Strategy pattern
Tags: programming, java, codequality, oop
Published: 2021-12-14 07:55:45

Strategy pattern is a design pattern that allows you to define a family of algorithms, put each of them into a separate class, and make their objects interchangeable.

This is useful when you have a large number of similar algorithms and you want to use them in different ways. It is one of the most common design patterns and is simple to understand and implement.

Strategy pattern is closely related to the Factory pattern -  the main difference is that Factory pattern is more useful for deciding the implementation at runtime whereas Strategy pattern is more useful for deciding the implementation while designing the application.

Let's start with some terminology.
1. **Strategy** - A strategy is an interface which defines a family of algorithms.
2. **Context** - A context is an object that uses a strategy to perform an operation.
3. **Concrete Strategy** - A concrete strategy is a class that implements an algorithm.
4. **Client** - A client is a class that tells the Context which strategy to use.

### A real world example
Let's think about an example of this in the real world. It is as simple as ordering a pizza.
- We have an oven which can cook a pizza. Consider it a context.
- The pizza is an abstraction. There can be many type of pizzas. So it is a strategy.
- The actual pizza that a customer selects is a concrete strategy.
- When the customer(the client) orders a specific pizza, the contents of the actual pizza are put into the oven, the oven starts to cook and the pizza is ready.

## Let's code this up

### The Strategy
Let's create a pizza interface.
```java
public interface Pizza {
    void prepare();
}
```

### The Concrete Strategy
Let's create multiple concrete strategies.

Our first strategy is a NY Style pizza.
```java
public class NYStyleCheesePizza implements Pizza {
    @Override
    public void prepare() {
        System.out.println("Preparing NY Style Sauce and Cheese Pizza");
    }
}
```

The other is a Pineapple pizza.
```java
public class PineapplePizza implements Pizza {
    @Override
    public void prepare() {
        System.out.println("Preparing Pineapple Pizza even though it is not a real pizza");
    }
}
```

### The Context
Let's create a context class for our Oven.
```java
public class Oven {
    private Pizza pizza;
    public Oven(Pizza pizza) {
        this.pizza = pizza;
    }
    public void bake() {
        pizza.prepare();
    }
}
```

### The Client
Now, let's create a client class.
```java
public class Client {
    public static void main(String[] args) {
        Oven oven = new Oven(new NYStyleCheesePizza());
        oven.bake();
    }
}
```
Considering the customer orders a NY Style pizza, the oven will start to cook the NY Style pizza.

## Advantages of using Strategy Pattern
1. Flexible context - You can change the strategy at runtime or even at design time but the context code doesnt have to change.
2. Easy to extend - You can add more strategies without having to change the context code.
3. Easier to test - You can test the code easily. All you have to do is pass in a mock strategy object to the context.

Strategy pattern is something you might be using already without even knowing it. It is intuitive and easy to understand.

If we talk about modern Java, the most popular occurrence of Strategy pattern is through [Spring Qualifiers](https://www.baeldung.com/spring-qualifier-annotation)

---


Thanks for reading! This should help you understand the concept of strategy pattern. Stay tuned for more design patterns.
If you want to connect with me, you can find me on Twitter [@abh1navv](https://twitter.com/abh1navv)