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.
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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
