Strategy Pattern: Swapping Algorithms

Stop using massive if-else blocks for different behaviors. Learn how the Strategy pattern makes your algorithms interchangeable and your code OCP-compliant.

April 22, 20242 min read1 / 2

The Strategy Design Pattern is used whenever you have a functionality that can be implemented in different, interchangeable ways.

The Problem: The if-else Nightmare

Imagine you are building Google Maps. The "Find Path" logic depends on the mode of transport:

  • if (mode == CAR) { // 50 lines of logic }
  • else if (mode == BIKE) { // 50 lines of logic }
  • else if (mode == WALK) { // 50 lines of logic }

This violates the Open-Closed Principle. Every time Google adds a "Scooter" mode, you have to modify this core class, potentially breaking existing code.

The Solution: Interchangeable Strategies

We move each algorithm into its own class that implements a common interface.

Java Implementation

Java
public interface PathStrategy { void findPath(String from, String to); } public class CarStrategy implements PathStrategy { public void findPath(String from, String to) { /* Car logic */ } } public class MapsApp { private PathStrategy strategy; public void setStrategy(PathStrategy s) { this.strategy = s; } public void execute() { strategy.findPath("A", "B"); } }

Java vs. JavaScript Perspective

1. In Java (Polymorphism)

Java developers use Strategy to maintain clean, decoupled codebases. It's often combined with a Factory to decide which strategy to instantiate at runtime.

2. In JavaScript / TypeScript (First-Class Functions)

In JS, we often don't even need separate classes! Since functions are "first-class citizens," we can just pass the algorithm directly:

TypeScript
const carStrategy = (from, to) => { /* ... */ }; const walkStrategy = (from, to) => { /* ... */ }; const findPath = (strategy, from, to) => strategy(from, to); findPath(carStrategy, "A", "B");

This is a "Functional" version of the Strategy pattern, which is much more idiomatic in modern React or Node.js apps.


Real-World Examples

  • Sorting: Choosing between QuickSort or MergeSort based on data size.
  • Payments: Switching between CreditCard, PayPal, or Crypto at checkout.
  • Compression: Using ZIP or RAR depending on user choice.

In our next part, we will explore the Observer Pattern--the backbone of modern event-driven systems.