Strategy Design Pattern

The Strategy Design Pattern is a behavioral design pattern that enables selecting an algorithm’s behavior at runtime. Instead of implementing multiple algorithms directly within a class, the strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. This pattern allows the algorithm to vary independently from the clients that use it.

Key Components of Strategy Design Pattern

  1. Strategy Interface: Defines a common interface for all algorithms.

  2. Concrete Strategies: Classes implementing the strategy interface with specific behaviors.

  3. Context: Holds a reference to a Strategy object and allows setting or changing the strategy at runtime.

Use Case Example: Car Payment System

Suppose we have a Car Rental Service where users can pay using different payment methods like credit card, PayPal, or cryptocurrency. Using the Strategy pattern allows us to encapsulate each payment method and change the payment behavior at runtime.

Implementation in Java (Spring Boot)

  1. Define the Strategy Interface:

    public interface PaymentStrategy {
        void pay(double amount);
    }
  2. Implement Concrete Strategies:

    // CreditCardPayment.java
    public class CreditCardPayment implements PaymentStrategy {
        @Override
        public void pay(double amount) {
            System.out.println("Paid " + amount + " using Credit Card.");
        }
    }
    
    // PayPalPayment.java
    public class PayPalPayment implements PaymentStrategy {
        @Override
        public void pay(double amount) {
            System.out.println("Paid " + amount + " using PayPal.");
        }
    }
    
    // CryptoPayment.java
    public class CryptoPayment implements PaymentStrategy {
        @Override
        public void pay(double amount) {
            System.out.println("Paid " + amount + " using Cryptocurrency.");
        }
    }
  3. Create the Context Class:

    public class PaymentContext {
        private PaymentStrategy paymentStrategy;
    
        public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
            this.paymentStrategy = paymentStrategy;
        }
    
        public void executePayment(double amount) {
            if (paymentStrategy == null) {
                throw new IllegalStateException("Payment strategy not set.");
            }
            paymentStrategy.pay(amount);
        }
    }
  4. Using the Strategy Pattern in the Application:

    public class CarRentalServiceApplication {
        public static void main(String[] args) {
            PaymentContext paymentContext = new PaymentContext();
    
            // Using Credit Card Payment
            paymentContext.setPaymentStrategy(new CreditCardPayment());
            paymentContext.executePayment(100.0);
    
            // Switching to PayPal Payment
            paymentContext.setPaymentStrategy(new PayPalPayment());
            paymentContext.executePayment(150.0);
    
            // Switching to Cryptocurrency Payment
            paymentContext.setPaymentStrategy(new CryptoPayment());
            paymentContext.executePayment(200.0);
        }
    }

Explanation

  • Strategy Interface (PaymentStrategy): Defines a pay() method, which each payment method (strategy) must implement.

  • Concrete Strategies: CreditCardPayment, PayPalPayment, and CryptoPayment each implement the PaymentStrategy interface, providing different payment behaviors.

  • Context Class (PaymentContext): Holds a reference to PaymentStrategy and executes the pay() method based on the chosen strategy.

Advantages of the Strategy Pattern

  1. Easily Changeable Behavior: You can switch between algorithms or behaviors at runtime by changing the strategy.

  2. Single Responsibility Principle: Each strategy encapsulates a specific behavior, making the code cleaner and easier to maintain.

  3. Open/Closed Principle: You can add new strategies without modifying existing code.

Real-World Analogy

Consider booking a rental car and being able to pay with different methods—credit card, PayPal, or cryptocurrency. Depending on the customer's choice, the system uses the appropriate payment strategy, making it flexible and easy to extend with additional payment options if needed.

Last updated