📢 This article was translated by gemini-2.5-flash
Strategy Pattern: Object Behavioral Pattern
Intent
Defines a family of algorithms, encapsulates each one, and makes them interchangeable. This pattern allows an algorithm to vary independently from the clients that use it.
Structure

Here’s the breakdown:
Strategy: Defines a common interface for all supported algorithms. The Context uses this interface to call an algorithm defined by a ConcreteStrategy.
ConcreteStrategy: Implements a specific algorithm using the Strategy interface.
Context: Is configured with a ConcreteStrategy object; maintains a reference to a Strategy object; can define an interface to allow the Strategy to access its data.
Applicability
The Strategy pattern is useful when:
Many related classes differ only in their behavior. The “Strategy” provides a way to configure a class with one of multiple behaviors.
You need different variants of an algorithm. For example, algorithms that reflect different space/time tradeoffs. When these variants are implemented as a class hierarchy for an algorithm, the Strategy pattern can be used.
An algorithm uses data that clients shouldn’t know about. The Strategy pattern can hide complex, algorithm-specific data structures from clients.
A class defines many behaviors, and these appear as multiple conditional statements within its operations. Move related conditional branches into their respective Strategy classes to replace these statements.
Example 1
A large shopping mall wants to develop cashier software that supports various promotional activities over different periods, such as discounts or cashback (e.g., spend 300, get 100 back). The Strategy pattern is used to meet this requirement. The designed class diagram is shown below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
| import java.util.*;
enum TYPE { NORMAL, CASH_DISCOUNT, CASH_RETURN};
interface CashSuper {
public double acceptCash(double money);
}
class CashNormal implements CashSuper { // Normal charging subclass
public double acceptCash(double money) {
return money;
}
}
class CashDiscount implements CashSuper {
private double moneyDiscount; // Discount rate
public CashDiscount(double moneyDiscount) {
this.moneyDiscount = moneyDiscount;
}
public double acceptCash(double money) {
return money * moneyDiscount;
}
}
class CashReturn implements CashSuper { // Full amount cashback
private double moneyCondition;
private double moneyReturn;
public CashReturn(double moneyCondition, double moneyReturn) {
this.moneyCondition = moneyCondition; // Threshold amount
this.moneyReturn = moneyReturn; // Cashback amount
}
public double acceptCash(double money) {
double result = money;
if(money >= moneyCondition )
result = money - Math.floor(money / moneyCondition) * moneyReturn;
return result;
}
}
class CashContext {
private CashSuper cs;
private TYPE t;
public CashContext(TYPE t) {
switch(t) {
case NORMAL: // Normal charge
cs = new CashNormal();
break;
case CASH_DISCOUNT: // 20% off
cs = new CashDiscount(0.8);
break;
case CASH_RETURN: // Spend 300, get 100 back
cs = new CashReturn(300, 100);
break;
}
}
public double GetResult(double money) {
return cs.acceptCash(money);
}
// main() method omitted for brevity
}
|
Example 2
Addition, Subtraction, Multiplication
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| public class StrategyPattern {
public static void main(String[] args) {
Strategy add = new AddStrategy();
Strategy subtraction = new SubtractionStrategy();
Strategy multiply = new MultiplyStrategy();
OperationContext context = new OperationContext(add);
context.Operation(1, 2);
context = new OperationContext(subtraction);
context.Operation(1, 2);
context = new OperationContext(multiply);
context.Operation(1, 2);
}
}
class OperationContext{
private Strategy strategy;
public OperationContext(Strategy strategy){
this.strategy = strategy;
}
public void Operation(int a, int b){
strategy.operation(a, b);
}
}
interface Strategy{
public void operation(int a, int b);
}
class AddStrategy implements Strategy{
@Override
public void operation(int a, int b){
System.out.println(a + b);
}
}
class SubtractionStrategy implements Strategy{
@Override
public void operation(int a, int b){
System.out.println(a - b);
}
}
class MultiplyStrategy implements Strategy{
@Override
public void operation(int a, int b){
System.out.println(a * b);
}
}
|