Strategy Pattern

Learn how to use the Strategy pattern to define a family of algorithms, encapsulate each one, and make them interchangeable, allowing the algorithm to vary independently from clients.

Table of Contents

1. Introduction

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

This pattern allows the algorithm to vary independently from the clients that use it, promoting the Open/Closed Principle.

2. Problem Statement

Consider a payment processing system:

  • Different payment methods: Credit Card, PayPal, Bank Transfer
  • Each has different processing logic
  • Without Strategy: Large if-else or switch statements
  • Hard to add new payment methods
Problem: Adding a new payment method requires modifying existing code, violating Open/Closed Principle.

3. Solution

The Strategy pattern solves this by:

  1. Defining a strategy interface for the algorithm
  2. Creating concrete strategy classes for each algorithm
  3. Using composition to inject strategy into context
  4. Allowing runtime strategy selection

4. Implementation

4.1 Java Example: Payment Processing

Step 1: Strategy Interface
public interface PaymentStrategy {
    void pay(double amount);
}
Step 2: Concrete Strategies
public class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;
    
    public CreditCardPayment(String cardNumber) {
        this.cardNumber = cardNumber;
    }
    
    @Override
    public void pay(double amount) {
        System.out.println("Paid " + amount + " using Credit Card: " + cardNumber);
    }
}

public class PayPalPayment implements PaymentStrategy {
    private String email;
    
    public PayPalPayment(String email) {
        this.email = email;
    }
    
    @Override
    public void pay(double amount) {
        System.out.println("Paid " + amount + " using PayPal: " + email);
    }
}
Step 3: Context
public class PaymentContext {
    private PaymentStrategy strategy;
    
    public void setStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }
    
    public void executePayment(double amount) {
        if (strategy != null) {
            strategy.pay(amount);
        }
    }
}
Step 4: Client Usage
public class StrategyDemo {
    public static void main(String[] args) {
        PaymentContext context = new PaymentContext();
        
        // Use credit card
        context.setStrategy(new CreditCardPayment("1234-5678"));
        context.executePayment(100.0);
        
        // Switch to PayPal
        context.setStrategy(new PayPalPayment("user@example.com"));
        context.executePayment(200.0);
    }
}

5. Use Cases

Use Strategy pattern when:

  • You have multiple ways to perform a task
  • You want to avoid conditional statements for algorithm selection
  • You want to add new algorithms without modifying existing code
  • Algorithms should be interchangeable

5.1 Real-World Examples

  • Sorting: Different sorting algorithms
  • Compression: ZIP, RAR, 7Z strategies
  • Validation: Different validation rules
  • Pricing: Different pricing strategies

6. Advantages and Disadvantages

6.1 Advantages

  • Flexibility: Algorithms can be swapped at runtime
  • Open/Closed: Easy to add new strategies
  • Eliminates Conditionals: No if-else chains
  • Single Responsibility: Each strategy has one algorithm

6.2 Disadvantages

  • Complexity: More classes
  • Client Awareness: Clients must know strategies
Best Practice: Use Strategy when you have multiple algorithms for the same task. Consider functional interfaces in Java 8+ for simpler strategies.

Post a Comment

0 Comments