Menu
Coddy logo textTech

Strategy Pattern

Part of the Object Oriented Programming section of Coddy's Java journey — lesson 69 of 87.

The Strategy Pattern is a behavioral design pattern that lets you define a family of algorithms, encapsulate each one in its own class, and make them interchangeable. Instead of hardcoding a specific behavior, you can swap algorithms at runtime without changing the code that uses them.

Imagine a payment system that supports multiple payment methods. Without the Strategy Pattern, you'd end up with messy conditional logic. With it, each payment method becomes its own strategy:

interface PaymentStrategy {
    void pay(int amount);
}

class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via Credit Card");
    }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via PayPal");
    }
}

The context class holds a reference to a strategy and delegates the work to it. The key is that the context doesn't know which concrete strategy it's using—it only knows the interface:

class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    
    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.paymentStrategy = strategy;
    }
    
    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}

Now you can change the payment behavior dynamically:

ShoppingCart cart = new ShoppingCart();

cart.setPaymentStrategy(new CreditCardPayment());
cart.checkout(100);  // Paid 100 via Credit Card

cart.setPaymentStrategy(new PayPalPayment());
cart.checkout(50);   // Paid 50 via PayPal

The Strategy Pattern shines when you have multiple ways to perform an action and want to switch between them easily. Adding a new payment method simply means creating a new class that implements PaymentStrategy—no changes to existing code required.

challenge icon

Challenge

Easy

Let's build a text formatting system using the Strategy Pattern! You'll create a system where different formatting strategies can be swapped at runtime to transform text in various ways—perfect for an application that needs to support multiple output formats.

You'll organize your code across four files:

  • TextFormatter.java: Define the TextFormatter interface that all formatting strategies will implement. It should declare a single method String format(String text) that takes a string and returns the formatted version.
  • Formatters.java: Create three concrete strategies that implement your TextFormatter interface:

    UpperCaseFormatter - transforms the text to all uppercase letters.

    LowerCaseFormatter - transforms the text to all lowercase letters.

    TitleCaseFormatter - capitalizes the first letter of each word while making the rest lowercase. Words are separated by spaces.

  • TextEditor.java: Create the context class that uses a formatting strategy. Your TextEditor should have:

    A private field to hold the current TextFormatter strategy.

    A setFormatter(TextFormatter formatter) method that changes the active formatting strategy.

    A publishText(String text) method that applies the current formatter to the text and prints Published: [formatted text]. If no formatter has been set, it should print Published: [original text] unchanged.

  • Main.java: Bring your strategy system together! You'll receive two inputs: the text to format (String) and the formatting style (String: "upper", "lower", or "title").

    Create a TextEditor and first call publishText with your input text before setting any formatter (demonstrating the default behavior).

    Then, based on the style input, set the appropriate formatter strategy and call publishText again with the same text to show the formatted result.

You will receive two inputs in order: the text to format (String) and the formatting style (String).

For example, with inputs hello world and title, your output would be:

Published: hello world
Published: Hello World

Notice how the TextEditor doesn't know anything about the specific formatting logic—it simply delegates to whatever strategy is currently set. This makes it trivial to add new formatting styles without touching the editor code!

Cheat sheet

The Strategy Pattern is a behavioral design pattern that defines a family of algorithms, encapsulates each one in its own class, and makes them interchangeable. It allows swapping algorithms at runtime without changing the code that uses them.

Key Components

Strategy Interface: Defines the common interface for all concrete strategies.

interface PaymentStrategy {
    void pay(int amount);
}

Concrete Strategies: Implement the strategy interface with specific algorithms.

class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via Credit Card");
    }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via PayPal");
    }
}

Context Class: Holds a reference to a strategy and delegates work to it. The context only knows the interface, not the concrete implementation.

class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    
    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.paymentStrategy = strategy;
    }
    
    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}

Usage

Strategies can be changed dynamically at runtime:

ShoppingCart cart = new ShoppingCart();

cart.setPaymentStrategy(new CreditCardPayment());
cart.checkout(100);  // Paid 100 via Credit Card

cart.setPaymentStrategy(new PayPalPayment());
cart.checkout(50);   // Paid 50 via PayPal

Benefits

The Strategy Pattern is ideal when you have multiple ways to perform an action and want to switch between them easily. Adding a new strategy simply means creating a new class that implements the strategy interface—no changes to existing code required.

Try it yourself

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String text = scanner.nextLine();
        String style = scanner.nextLine();
        
        // TODO: Create a TextEditor instance
        
        // TODO: Call publishText with the input text (before setting any formatter)
        
        // TODO: Based on the style input ("upper", "lower", or "title"),
        // set the appropriate formatter and call publishText again
        
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming