How the Strategy Pattern works?
Tags: designpatterns, go, tutorial, beginners
Published: 2022-06-09 01:05:01

## Overview

Have you ever entered to an e-commerce and buy a product?, If you have, then you may have been show different ways to pay (PayPal, Credit Card, etc.)

![Strategy pattern description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2vp6dh0hyi9xpvhs0jkk.png) 

This purchase process is a way to see the Strategy Pattern. **Strategy** is a Behavioral design pattern that lets you define different strategies and switch between them to reach a goal. In the above image, you have a goal (buy a product) and different strategies to accomplish it (pay with PayPal, Credit Card, etc.).

Let’s see how we would implement this purchase process.

### Structure of Strategy Pattern

First, let's understand the structure of the pattern. It is defined by 3 parts:

1. Context Class
    
    This is our goal
    
2. Contract Interface
    
    These are the rules to be followed by the Strategies
    
3. Strategy Classes
    
     Refers to the different strategies to reach my goal, are the implementation of the `Contract Interface`
    

Here is a Class Diagram for the **Strategy** structure

![Strategy Pattern Class Diagram description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g4mtsa2u18oquk39fho2.png) 

Will also need a Client who trigger the purchase process. Will see this in the code examples.

## Code time, yay!

Now, let’s take the Class Diagram into code to see how it is done. I’ll be using [Golang](https://go.dev/) because it is the language I’m comfortable with:

1. Define the Contract Interface
![Contract definiton](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ulk19bseyp6ajhygdzub.png)
     
2. Define the Context
![Purchase context implenmentation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uvuxeho8odcamfaiu6bm.png) 
3. Implement the Strategies
    For this, will have 3 different classes (PayPal, CreditCard and Bank)
![PayPal strategy implementation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ob8n5yuctxszvirgzl0.png)![CreditCard strategy implementation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/luj607lu9b7iogc7997m.png)![Bank strategy implementation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g70pacmsn43hz232xpz0.png)
 
4. Client
    
    In this example, I’ll be using the console to execute the purchase process.
![Client](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i3mgc2d6a9u7swdpobqr.png)

When we run our program, this is what happen:

![Strategy terminal example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u9c2y8iklsd5fe57rnzk.gif) 

<aside>
ℹ️ **Note:** This pattern is a way to implement the Open/Closed Principle of SOLID.

</aside>

### What if we want to add another payment method?

This would be easy, you just have to create another class that implements the `PaymentMethodStrategy` interface:![Bitcoin strategy implementation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fi2soxhvbw1z7d9cmd6z.png)

and after that, you just have to register it in your context class

![Bitcoin registry](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mkzpttiz3xrboek0m55m.png) 

## The conventional way

***How would it be to implement this process without the Strategy pattern?***

Well, instead of having 3 classes (Context, Contract and Strategies), we’ll only have 1 class that implements all the logic to pay with PayPal, CreditCard, Bank, etc.

1. This will be our Purchase Class that implements all the logic
![Classic implementation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kmtazlf8z22868ho7ljz.png)![Classic implementation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5agllzmyp476wifcxm05.png)
2. Our client
![Classic implementation client](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/si5uqbqgsdtyxv0rgx1y.png) 

When we run our program, this is what happen:

![Classic example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pmb7kuulek8o4x1x0dm4.gif) 

This could be fine when you first build your app, or when you know that you’ll rarely will add or modify existent logic. But if you know that the business logic will grow, things like this may happen in the future:

1. It will be difficult to navigate throughout the code 
2. Highly chance you modify something you’re not supposed to
3. Git conflicts when different people working on the same class
4. A lot of conditionals to switch between the different payment methods

From the business perspective it may be ok because it works, but from the technical perspective is not because it will not be maintainable in the future.

<aside>
ℹ️ **Note:** Putting all the logic in one class, for this example, will go against the Single Responsibility Principle of SOLID.

</aside>

## Practice

Here I showed what the Strategy Pattern is, how it is structured, and when you should use this pattern instead of putting all the logic in one class.

I invite you to implement this pattern to apply a discount to an order and share the code in the comments. Hope this blog helped you understand the Strategy pattern. See you in the next Design Pattern article of this series.

## References

1. [Dive into Design Patterns](https://refactoring.guru/design-patterns/book): **This article is made by the notes I took from this book**
    
2. [Peek](https://github.com/phw/peek): **Tool to record my terminal**
    
3. [Figma Jam](https://www.figma.com/figjam/) and [IconDuck](https://iconduck.com/): **To make the illustrations**

4. [Ray.so](https://ray.so/): **For the code images**
    
4. [Article repository](https://github.com/hernanhrm/strategy-pattern): **You can find the examples in my GitHub**