DEV Community

Diallo Mamadou Pathé
Diallo Mamadou Pathé

Posted on • Updated on

Strategy Design Pattern in Java

The Strategy Design Pattern is a behavioral design pattern that enables selecting an algorithm's behavior at runtime. It defines a family of algorithms, encapsulates each one, and makes them interchangeable. The pattern lets the algorithm vary independently from the clients that use it. This is particularly useful when you want to swap or change algorithms without affecting the client code.

strategy design pattern

Key Concepts:

  • Strategy Interface: Declares an interface common to all supported algorithms.

  • Concrete Strategies: Implement different variations of the algorithm.

  • Context: Uses a reference to the Strategy interface to call the algorithm defined by a Concrete Strategy.

This pattern is useful when you have multiple ways of performing an operation, and the decision of which to use can change dynamically.

Example Scenario: Payment Methods

Let's consider an online shopping platform where a user can choose different payment methods (e.g., PayPal, CreditCard, etc.). The strategy pattern allows switching between different payment strategies without altering the core logic.

Java Example:
1. Strategy Interface:

public interface PaymentStrategy {
    void pay(int amount);
    String getPaymentType();
}
Enter fullscreen mode Exit fullscreen mode

2. Concrete Strategy Classes:

public class CreditCardPayment implements PaymentStrategy {
    private String name;
    private String cardNumber;

    public CreditCardPayment(String name, String cardNumber) {
        this.name = name;
        this.cardNumber = cardNumber;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid with Credit Card.");
    }

    @Override
    public String getPaymentType() {
        return "Credit Card";
    }
}
Enter fullscreen mode Exit fullscreen mode
public class PayPalPayment implements PaymentStrategy {
    private String email;

    public PayPalPayment(String email) {
        this.email = email;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid using PayPal.");
    }

    @Override
    public String getPaymentType() {
        return "PayPal";
    }
}

Enter fullscreen mode Exit fullscreen mode

3. Context Class:

public class ShoppingCart {
    private PaymentStrategy paymentStrategy;

    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}
Enter fullscreen mode Exit fullscreen mode

4. Client Code:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        Scanner scanner = new Scanner(System.in);

        List<PaymentStrategy> paymentStrategies = new ArrayList<>();
        paymentStrategies.add(new CreditCardPayment("John Doe", "1234-5678-9012-3456"));
        paymentStrategies.add(new PayPalPayment("john@example.com"));

        System.out.println("Available Payment Methods:");
        for (int i = 0; i < paymentStrategies.size(); i++) {
            System.out.println((i + 1) + ". " + paymentStrategies.get(i).getPaymentType());
        }

        System.out.print("Choose a payment method by number: ");
        int choice = scanner.nextInt();

        if (choice > 0 && choice <= paymentStrategies.size()) {
            cart.setPaymentStrategy(paymentStrategies.get(choice - 1));

            System.out.print("Enter the amount to pay: ");
            int amount = scanner.nextInt();
            cart.checkout(amount);
        } else {
            System.out.println("Invalid choice.");
        }

        scanner.close();
    }
}
Enter fullscreen mode Exit fullscreen mode

Output:

Available Payment Methods:
1. Credit Card
2. PayPal
Choose a payment method by number: 1
Enter the amount to pay: 12
12 paid with Credit Card.
Enter fullscreen mode Exit fullscreen mode

Benefits of the Strategy Pattern:

  1. Open/Closed Principle: New strategies can be added without modifying the client code.

  2. Avoids Conditional Statements: You avoid multiple conditional if/else or switch blocks to choose algorithms.

  3. Runtime Flexibility: Strategies can be changed at runtime.

When to Use:

  • When multiple related classes differ only in their behavior (algorithm).
  • When you need different variants of an algorithm and want to switch them dynamically.
  • When you want to avoid complex conditional logic.

This pattern is particularly useful when the selection of an algorithm needs to happen dynamically, and it simplifies code management for algorithms that may evolve independently.

Top comments (1)

Collapse
 
didate profile image
Lamarana Diallo

Useful article on the Strategy DP.