Fundamentals 10 min read

Understanding the Strategy Design Pattern in Java

This article introduces the Strategy design pattern, explains its definition, class diagram, Java implementation examples, advantages and disadvantages, and demonstrates its use in JDK components such as Comparator and ThreadPoolExecutor, helping developers replace complex if‑else logic with interchangeable algorithm objects.

Full-Stack Internet Architecture
Full-Stack Internet Architecture
Full-Stack Internet Architecture
Understanding the Strategy Design Pattern in Java

Keeper Introduction: The author recently inherited a project with a tangled if‑else chain of nearly ten branches and decided to refactor it using the Strategy design pattern.

Definition : The Strategy pattern (Strategy Design Pattern) encapsulates interchangeable behaviors and delegates the choice of which behavior to use at runtime. It is a behavioral design pattern that lets you define a family of algorithms, place each in its own class, and make them interchangeable.

In plain language: you pass a different "key" to a method at runtime, and the method executes different business logic – essentially what a long if‑else chain does.

Below is a typical multi‑branch if‑else example that the author wants to replace:

public String getCheckResult(String type) {
  if ("校验1".equals(type)) {
    return "执行业务逻辑1";
  } else if ("校验2".equals(type)) {
    return "执行业务逻辑2";
  }
  // ... more branches ...
  return "不在处理的逻辑中返回业务错误";
}

The Strategy pattern can avoid such lengthy conditional statements and also provide extension points similar to the Template Method pattern.

Class Diagram

The pattern involves three roles:

Strategy : an interface or abstract class that defines the family of algorithms.

ConcreteStrategy : concrete classes that implement the Strategy interface.

Context : holds a reference to a Strategy object and delegates work to it.

Java Demo

1. Strategy interface:

public interface Strategy {
    void operate();
}

2. Concrete strategies:

public class ConcreteStrategyA implements Strategy {
    @Override
    public void operate() {
        System.out.println("执行业务逻辑A");
    }
}

public class ConcreteStrategyB implements Strategy {
    @Override
    public void operate() {
        System.out.println("执行业务逻辑B");
    }
}

3. Context class:

public class Context {
    private Strategy strategy;
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }
    public void doSomething() {
        strategy.operate();
    }
}

4. Client usage:

public static void main(String[] args) {
    Context context = new Context(new ConcreteStrategyA());
    context.doSomething();
}
In practice, this static usage is as rigid as a long if‑else chain; typically a factory is combined to decide the concrete strategy at runtime.

Analysis of the Strategy Pattern

The pattern separates algorithm implementations from business logic, allowing each algorithm to be swapped independently. It does not change the underlying functionality, only the way the code is organized.

Who chooses the concrete strategy?

Client: the caller explicitly selects a strategy (as in the demo).

Context: the context decides internally, often via a factory.

Pros

Avoids massive conditional statements.

Improves extensibility and adheres to the Open/Closed Principle.

Cons

Clients must understand each strategy (mitigated by IoC/DI).

Increases the number of classes.

Suitable only for flat algorithm structures; not for nested hierarchies.

Strategy Pattern in the JDK

The Comparator interface is a classic example of a strategy; its compare() method defines the sorting rule. Custom comparators implement this interface to provide bespoke ordering.

public interface Comparator<T> {
    int compare(T o1, T o2);
    // ...
}

Example of a custom comparator used with Arrays.sort:

public static void main(String[] args) {
    Integer[] data = {4,2,7,5,1,9};
    Comparator<Integer> comparator = new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            if (o1 > o2) {
                return 1;
            } else {
                return -1;
            }
        }
    };
    Arrays.sort(data, comparator);
    System.out.println(Arrays.toString(data));
}

The JDK also uses the Strategy pattern for thread‑pool rejection policies ( RejectedExecutionHandler) and other extensible components.

Conclusion

The Strategy pattern is not a magic solution that eliminates if‑else entirely; it merely relocates the conditional logic into separate, interchangeable classes, making the codebase more maintainable and extensible when many algorithms coexist.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsjavaStrategy Patternrefactoring
Full-Stack Internet Architecture
Written by

Full-Stack Internet Architecture

Introducing full-stack Internet architecture technologies centered on Java

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.