Strategy Design Pattern (original) (raw)

Last Updated : 14 May, 2026

The Strategy Design Pattern is a behavioral pattern that defines a group of related algorithms, encapsulates each one in a separate class, and makes them interchangeable. It allows the algorithm to vary independently from the client that uses it, enabling behavior changes at runtime without altering existing code.

**Example: A payment system where a user (client) selects a payment method, and the system (context) applies a strategy like Credit Card, UPI, or PayPal to process the payment.

Strategy-design-pattern

Strategy Design Pattern

In the Diagram

Real-Life Software Applications

Some real-world examples where the Strategy Pattern is commonly used are:

Components

The Strategy Design Pattern consists of key components that work together to define and use interchangeable algorithms.

components_of_strategy_design_pattern

Components

1. Context

Acts as an intermediary between the client and the strategy, delegating tasks to the selected strategy.

2. Strategy Interface

Defines a common interface that all concrete strategies must implement.

3. Concrete Strategies

Provide specific implementations of the strategy interface with different algorithms or behaviors.

4. Client

Responsible for selecting and configuring the appropriate strategy for the context.

Working

The Strategy pattern works by delegating a specific task to interchangeable algorithm classes.

Uses

The Strategy pattern is used when an application needs to choose different behaviors or algorithms dynamically based on context.

Implementation Example

Problem Statement

Consider a sorting application where we need to sort a list of integers. However, the sorting algorithm to be used may vary depending on factors such as the size of the list and the desired performance characteristics.

Challenges Without Using Strategy Pattern:

Benefits of Using the Strategy Pattern to solve above challenges

Here's how the Strategy Pattern helps:

class_diagram_of_strategy_design_pattern_2

Class Diagram

This example shows the practical application of the design pattern using code.

1. Context(SortingContext)

C++ `

#include using namespace std;

// Strategy Interface (Abstract Class) class SortingStrategy { public: virtual void sort(int arr[], int size) = 0; // pure virtual function virtual ~SortingStrategy() {} // virtual destructor };

// Context Class class SortingContext { private: SortingStrategy* sortingStrategy;

public: // Constructor SortingContext(SortingStrategy* strategy) { this->sortingStrategy = strategy; }

// Setter to change strategy
void setSortingStrategy(SortingStrategy* strategy) {
    this->sortingStrategy = strategy;
}

// Perform sort
void performSort(int arr[], int size) {
    if (sortingStrategy)
        sortingStrategy->sort(arr, size);
}

};

Java

import java.util.Arrays;

// Strategy Interface (Abstract Class) interface SortingStrategy { void sort(String[] arr, int size); // pure virtual function }

// Context Class class SortingContext { private SortingStrategy sortingStrategy;

// Constructor
public SortingContext(SortingStrategy strategy) {
    this.sortingStrategy = strategy;
}

// Setter to change strategy
public void setSortingStrategy(SortingStrategy strategy) {
    this.sortingStrategy = strategy;
}

// Perform sort
public void performSort(String[] arr, int size) {
    if (sortingStrategy!= null)
        sortingStrategy.sort(arr, size);
}

}

// Example concrete strategy class AlphabeticalSort implements SortingStrategy { @Override public void sort(String[] arr, int size) { Arrays.sort(arr); } }

Python

from abc import ABC, abstractmethod

class SortingStrategy(ABC): @abstractmethod def sort(self, array): pass

class SortingContext: def init(self, sorting_strategy): self.sorting_strategy = sorting_strategy

def set_sorting_strategy(self, sorting_strategy):
    self.sorting_strategy = sorting_strategy

def perform_sort(self, array):
    self.sorting_strategy.sort(array)

JavaScript

class SortingStrategy { sort(array) { throw new Error('sort method must be implemented'); } }

class SortingContext { constructor(sortingStrategy) { this.sortingStrategy = sortingStrategy; }

setSortingStrategy(sortingStrategy) {
    this.sortingStrategy = sortingStrategy;
}

performSort(array) {
    this.sortingStrategy.sort(array);
}

}

`

2. Strategy Interface(SortingStrategy)

C++ `

public interface SortingStrategy { void sort(int[] array); }

Java

public interface SortingStrategy { void sort(int[] array); // Implement sorting logic here }

Python

from abc import ABC, abstractmethod

class SortingStrategy(ABC): @abstractmethod def sort(self, array): pass

# Implement sorting logic here
def sort(self, array):
    array.sort()

JavaScript

const SortingStrategy = { sort: function(array) { // Implement sorting logic here array.sort(); } };

`

3. Concrete Strategies

C++ `

#include using namespace std;

// Assuming SortingStrategy is already defined as an abstract class

// BubbleSortStrategy class BubbleSortStrategy : public SortingStrategy { public: void sort(int arr[], int size) override { // Implement Bubble Sort algorithm cout << "Sorting using Bubble Sort" << endl; } };

// MergeSortStrategy class MergeSortStrategy : public SortingStrategy { public: void sort(int arr[], int size) override { // Implement Merge Sort algorithm cout << "Sorting using Merge Sort" << endl; } };

// QuickSortStrategy class QuickSortStrategy : public SortingStrategy { public: void sort(int arr[], int size) override { // Implement Quick Sort algorithm cout << "Sorting using Quick Sort" << endl; } };

Java

// BubbleSortStrategy public class BubbleSortStrategy implements SortingStrategy { @Override public void sort(int[] array) { // Implement Bubble Sort algorithm System.out.println("Sorting using Bubble Sort"); } }

// MergeSortStrategy public class MergeSortStrategy implements SortingStrategy { @Override public void sort(int[] array) { // Implement Merge Sort algorithm System.out.println("Sorting using Merge Sort"); } }

// QuickSortStrategy public class QuickSortStrategy implements SortingStrategy { @Override public void sort(int[] array) { // Implement Quick Sort algorithm System.out.println("Sorting using Quick Sort"); } }

Python

class BubbleSortStrategy: def sort(self, array): # Implement Bubble Sort algorithm print("Sorting using Bubble Sort")

class MergeSortStrategy: def sort(self, array): # Implement Merge Sort algorithm print("Sorting using Merge Sort")

class QuickSortStrategy: def sort(self, array): # Implement Quick Sort algorithm print("Sorting using Quick Sort")

JavaScript

class BubbleSortStrategy { sort(array) { // Implement Bubble Sort algorithm console.log("Sorting using Bubble Sort"); } }

class MergeSortStrategy { sort(array) { // Implement Merge Sort algorithm console.log("Sorting using Merge Sort"); } }

class QuickSortStrategy { sort(array) { // Implement Quick Sort algorithm console.log("Sorting using Quick Sort"); } }

`

4. Client Component

C++ `

#include using namespace std;

int main() { // Create strategies SortingStrategy* bubble = new BubbleSortStrategy(); SortingStrategy* merge = new MergeSortStrategy(); SortingStrategy* quick = new QuickSortStrategy();

// Create SortingContext with BubbleSortStrategy
SortingContext sortingContext(bubble);
int array1[] = {5, 2, 9, 1, 5};
sortingContext.performSort(array1, 5); // Output: Sorting using Bubble Sort

// Change strategy to MergeSortStrategy
sortingContext.setSortingStrategy(merge);
int array2[] = {8, 3, 7, 4, 2};
sortingContext.performSort(array2, 5); // Output: Sorting using Merge Sort

// Change strategy to QuickSortStrategy
sortingContext.setSortingStrategy(quick);
int array3[] = {6, 1, 3, 9, 5};
sortingContext.performSort(array3, 5); // Output: Sorting using Quick Sort

// Cleanup (important in C++)
delete bubble;
delete merge;
delete quick;

return 0;

}

Java

public interface SortingStrategy { void sort(String[] array); }

class BubbleSortStrategy implements SortingStrategy { @Override public void sort(String[] array) { System.out.println("Sorting using Bubble Sort"); // Bubble sort implementation } }

class MergeSortStrategy implements SortingStrategy { @Override public void sort(String[] array) { System.out.println("Sorting using Merge Sort"); // Merge sort implementation } }

class QuickSortStrategy implements SortingStrategy { @Override public void sort(String[] array) { System.out.println("Sorting using Quick Sort"); // Quick sort implementation } }

class SortingContext { private SortingStrategy strategy;

public SortingContext(SortingStrategy strategy) {
    this.strategy = strategy;
}

public void performSort(String[] array) {
    strategy.sort(array);
}

public void setSortingStrategy(SortingStrategy strategy) {
    this.strategy = strategy;
}

}

public class Client { public static void main(String[] args) { // Create SortingContext with BubbleSortStrategy SortingContext sortingContext = new SortingContext(new BubbleSortStrategy()); String[] array1 = {"cpp","c","java","python3","csharp","html","css","javascript","php","cpp14","cobol","dart","go","julia","kotlin","lisp","matlab","node","objc","perl","r","rust","ruby","scala","swift","solidity","xml"}; sortingContext.performSort(array1); // Output: Sorting using Bubble Sort

    // Change strategy to MergeSortStrategy
    sortingContext.setSortingStrategy(new MergeSortStrategy());
    String[] array2 = {"cpp","c","java","python3","csharp","html","css","javascript","php","cpp14","cobol","dart","go","julia","kotlin","lisp","matlab","node","objc","perl","r","rust","ruby","scala","swift","solidity","xml"};
    sortingContext.performSort(array2); // Output: Sorting using Merge Sort

    // Change strategy to QuickSortStrategy
    sortingContext.setSortingStrategy(new QuickSortStrategy());
    String[] array3 = {"cpp","c","java","python3","csharp","html","css","javascript","php","cpp14","cobol","dart","go","julia","kotlin","lisp","matlab","node","objc","perl","r","rust","ruby","scala","swift","solidity","xml"};
    sortingContext.performSort(array3); // Output: Sorting using Quick Sort
}

}

Python

from abc import ABC, abstractmethod

class SortingStrategy(ABC): @abstractmethod def sort(self, array): pass

class BubbleSortStrategy(SortingStrategy): def sort(self, array): print('Sorting using Bubble Sort') # Bubble sort implementation

class MergeSortStrategy(SortingStrategy): def sort(self, array): print('Sorting using Merge Sort') # Merge sort implementation

class QuickSortStrategy(SortingStrategy): def sort(self, array): print('Sorting using Quick Sort') # Quick sort implementation

class SortingContext: def init(self, strategy): self.strategy = strategy

def perform_sort(self, array):
    self.strategy.sort(array)

def set_sorting_strategy(self, strategy):
    self.strategy = strategy

Create SortingContext with BubbleSortStrategy

sorting_context = SortingContext(BubbleSortStrategy()) array1 = ['cpp','c','java','python3','csharp','html','css','javascript','php','cpp14','cobol','dart','go','julia','kotlin','lisp','matlab','node','objc','perl','r','rust','ruby','scala','swift','solidity','xml'] sorting_context.perform_sort(array1) # Output: Sorting using Bubble Sort

Change strategy to MergeSortStrategy

sorting_context.set_sorting_strategy(MergeSortStrategy()) array2 = ['cpp','c','java','python3','csharp','html','css','javascript','php','cpp14','cobol','dart','go','julia','kotlin','lisp','matlab','node','objc','perl','r','rust','ruby','scala','swift','solidity','xml'] sorting_context.perform_sort(array2) # Output: Sorting using Merge Sort

Change strategy to QuickSortStrategy

sorting_context.set_sorting_strategy(QuickSortStrategy()) array3 = ['cpp','c','java','python3','csharp','html','css','javascript','php','cpp14','cobol','dart','go','julia','kotlin','lisp','matlab','node','objc','perl','r','rust','ruby','scala','swift','solidity','xml'] sorting_context.perform_sort(array3) # Output: Sorting using Quick Sort

JavaScript

class SortingStrategy { sort(array) {} }

class BubbleSortStrategy extends SortingStrategy { sort(array) { console.log('Sorting using Bubble Sort'); // Bubble sort implementation } }

class MergeSortStrategy extends SortingStrategy { sort(array) { console.log('Sorting using Merge Sort'); // Merge sort implementation } }

class QuickSortStrategy extends SortingStrategy { sort(array) { console.log('Sorting using Quick Sort'); // Quick sort implementation } }

class SortingContext { constructor(strategy) { this.strategy = strategy; }

performSort(array) {
    this.strategy.sort(array);
}

setSortingStrategy(strategy) {
    this.strategy = strategy;
}

}

// Create SortingContext with BubbleSortStrategy let sortingContext = new SortingContext(new BubbleSortStrategy()); let array1 = ['cpp','c','java','python3','csharp','html','css','javascript','php','cpp14','cobol','dart','go','julia','kotlin','lisp','matlab','node','objc','perl','r','rust','ruby','scala','swift','solidity','xml']; sortingContext.performSort(array1); // Output: Sorting using Bubble Sort

// Change strategy to MergeSortStrategy sortingContext.setSortingStrategy(new MergeSortStrategy()); let array2 = ['cpp','c','java','python3','csharp','html','css','javascript','php','cpp14','cobol','dart','go','julia','kotlin','lisp','matlab','node','objc','perl','r','rust','ruby','scala','swift','solidity','xml']; sortingContext.performSort(array2); // Output: Sorting using Merge Sort

// Change strategy to QuickSortStrategy sortingContext.setSortingStrategy(new QuickSortStrategy()); let array3 = ['cpp','c','java','python3','csharp','html','css','javascript','php','cpp14','cobol','dart','go','julia','kotlin','lisp','matlab','node','objc','perl','r','rust','ruby','scala','swift','solidity','xml']; sortingContext.performSort(array3); // Output: Sorting using Quick Sort

`

Complete code for the above example

C++ `

#include #include

class SortingStrategy { public: virtual void sort(std::vectorstd::string& array) = 0; };

class BubbleSortStrategy : public SortingStrategy { public: void sort(std::vectorstd::string& array) override { std::cout << "Sorting using Bubble Sort" << std::endl; // Actual Bubble Sort Logic here } };

class MergeSortStrategy : public SortingStrategy { public: void sort(std::vectorstd::string& array) override { std::cout << "Sorting using Merge Sort" << std::endl; // Actual Merge Sort Logic here } };

class QuickSortStrategy : public SortingStrategy { public: void sort(std::vectorstd::string& array) override { std::cout << "Sorting using Quick Sort" << std::endl; // Actual Quick Sort Logic here } };

class SortingContext { private: SortingStrategy* sortingStrategy; public: SortingContext(SortingStrategy* sortingStrategy) : sortingStrategy(sortingStrategy) {}

void setSortingStrategy(SortingStrategy* sortingStrategy) {
    this->sortingStrategy = sortingStrategy;
}

void performSort(std::vector<std::string>& array) {
    sortingStrategy->sort(array);
}

};

int main() { std::vectorstd::string array1 = {"cpp","c","java","python3","csharp","html","css","javascript","php","cpp14","cobol","dart","go","julia","kotlin","lisp","matlab","node","objc","perl","r","rust","ruby","scala","swift","solidity","xml"}; SortingContext sortingContext(new BubbleSortStrategy()); sortingContext.performSort(array1); // Output: Sorting using Bubble Sort

sortingContext.setSortingStrategy(new MergeSortStrategy());
std::vector<std::string> array2 = {"cpp","c","java","python3","csharp","html","css","javascript","php","cpp14","cobol","dart","go","julia","kotlin","lisp","matlab","node","objc","perl","r","rust","ruby","scala","swift","solidity","xml"};
sortingContext.performSort(array2); // Output: Sorting using Merge Sort

sortingContext.setSortingStrategy(new QuickSortStrategy());
std::vector<std::string> array3 = {"cpp","c","java","python3","csharp","html","css","javascript","php","cpp14","cobol","dart","go","julia","kotlin","lisp","matlab","node","objc","perl","r","rust","ruby","scala","swift","solidity","xml"};
sortingContext.performSort(array3); // Output: Sorting using Quick Sort
return 0;

}

Java

class SortingContext { private SortingStrategy sortingStrategy;

public SortingContext(SortingStrategy sortingStrategy) {
    this.sortingStrategy = sortingStrategy;
}

public void setSortingStrategy(SortingStrategy sortingStrategy) {
    this.sortingStrategy = sortingStrategy;
}

public void performSort(int[] array) {
    sortingStrategy.sort(array);
}

}

// SortingStrategy.java interface SortingStrategy { void sort(int[] array); }

// BubbleSortStrategy.java class BubbleSortStrategy implements SortingStrategy { @Override public void sort(int[] array) { // Implement Bubble Sort algorithm System.out.println("Sorting using Bubble Sort"); // Actual Bubble Sort Logic here } }

// MergeSortStrategy.java class MergeSortStrategy implements SortingStrategy { @Override public void sort(int[] array) { // Implement Merge Sort algorithm System.out.println("Sorting using Merge Sort"); // Actual Merge Sort Logic here } }

// QuickSortStrategy.java class QuickSortStrategy implements SortingStrategy { @Override public void sort(int[] array) { // Implement Quick Sort algorithm System.out.println("Sorting using Quick Sort"); // Actual Quick Sort Logic here } }

// Client.java public class Client { public static void main(String[] args) { // Create SortingContext with BubbleSortStrategy SortingContext sortingContext = new SortingContext(new BubbleSortStrategy()); int[] array1 = {5, 2, 9, 1, 5}; sortingContext.performSort(array1); // Output: Sorting using Bubble Sort

    // Change strategy to MergeSortStrategy
    sortingContext.setSortingStrategy(new MergeSortStrategy());
    int[] array2 = {8, 3, 7, 4, 2};
    sortingContext.performSort(array2); // Output: Sorting using Merge Sort

    // Change strategy to QuickSortStrategy
    sortingContext.setSortingStrategy(new QuickSortStrategy());
    int[] array3 = {6, 1, 3, 9, 5};
    sortingContext.performSort(array3); // Output: Sorting using Quick Sort
}

}

Python

from abc import ABC, abstractmethod

class SortingStrategy(ABC): @abstractmethod def sort(self, array): pass

class BubbleSortStrategy(SortingStrategy): def sort(self, array): print('Sorting using Bubble Sort') # Actual Bubble Sort Logic here

class MergeSortStrategy(SortingStrategy): def sort(self, array): print('Sorting using Merge Sort') # Actual Merge Sort Logic here

class QuickSortStrategy(SortingStrategy): def sort(self, array): print('Sorting using Quick Sort') # Actual Quick Sort Logic here

class SortingContext: def init(self, sorting_strategy): self.sorting_strategy = sorting_strategy

def set_sorting_strategy(self, sorting_strategy):
    self.sorting_strategy = sorting_strategy

def perform_sort(self, array):
    self.sorting_strategy.sort(array)

Client

array1 = ["cpp","c","java","python3","csharp","html","css","javascript","php","cpp14","cobol","dart","go","julia","kotlin","lisp","matlab","node","objc","perl","r","rust","ruby","scala","swift","solidity","xml"] sorting_context = SortingContext(BubbleSortStrategy()) sorting_context.perform_sort(array1) # Output: Sorting using Bubble Sort

sorting_context.set_sorting_strategy(MergeSortStrategy()) array2 = ["cpp","c","java","python3","csharp","html","css","javascript","php","cpp14","cobol","dart","go","julia","kotlin","lisp","matlab","node","objc","perl","r","rust","ruby","scala","swift","solidity","xml"] sorting_context.perform_sort(array2) # Output: Sorting using Merge Sort

sorting_context.set_sorting_strategy(QuickSortStrategy()) array3 = ["cpp","c","java","python3","csharp","html","css","javascript","php","cpp14","cobol","dart","go","julia","kotlin","lisp","matlab","node","objc","perl","r","rust","ruby","scala","swift","solidity","xml"] sorting_context.perform_sort(array3) # Output: Sorting using Quick Sort

JavaScript

class SortingContext { constructor(sortingStrategy) { this.sortingStrategy = sortingStrategy; }

setSortingStrategy(sortingStrategy) {
    this.sortingStrategy = sortingStrategy;
}

performSort(array) {
    this.sortingStrategy.sort(array);
}

}

class SortingStrategy { sort(array) { throw new Error('This method should be overridden!'); } }

class BubbleSortStrategy extends SortingStrategy { sort(array) { console.log('Sorting using Bubble Sort'); // Actual Bubble Sort Logic here } }

class MergeSortStrategy extends SortingStrategy { sort(array) { console.log('Sorting using Merge Sort'); // Actual Merge Sort Logic here } }

class QuickSortStrategy extends SortingStrategy { sort(array) { console.log('Sorting using Quick Sort'); // Actual Quick Sort Logic here } }

// Client const sortingContext = new SortingContext(new BubbleSortStrategy()); const array1 = ['cpp','c','java','python3','csharp','html','css','javascript','php','cpp14','cobol','dart','go','julia','kotlin','lisp','matlab','node','objc','perl','r','rust','ruby','scala','swift','solidity','xml']; sortingContext.performSort(array1); // Output: Sorting using Bubble Sort

sortingContext.setSortingStrategy(new MergeSortStrategy()); const array2 = ['cpp','c','java','python3','csharp','html','css','javascript','php','cpp14','cobol','dart','go','julia','kotlin','lisp','matlab','node','objc','perl','r','rust','ruby','scala','swift','solidity','xml']; sortingContext.performSort(array2); // Output: Sorting using Merge Sort

sortingContext.setSortingStrategy(new QuickSortStrategy()); const array3 = ['cpp','c','java','python3','csharp','html','css','javascript','php','cpp14','cobol','dart','go','julia','kotlin','lisp','matlab','node','objc','perl','r','rust','ruby','scala','swift','solidity','xml']; sortingContext.performSort(array3); // Output: Sorting using Quick Sort

`

Output

Sorting using Bubble Sort Sorting using Merge Sort Sorting using Quick Sort

Advantages

This pattern improves flexibility and maintainability by separating behavior from the main logic.

Limitations

While flexible, the pattern can introduce additional complexity in the application design.