Understanding the Strategy Design Pattern with Java Examples
This article explains the Strategy design pattern, its definition, structure, and how to refactor a typical e‑commerce discount calculation in Java using interfaces, concrete strategy classes, and a context, highlighting benefits, drawbacks, and best‑practice considerations.
Design patterns are divided into creational, structural, and behavioral categories; the Strategy pattern belongs to the behavioral group and is widely used in JDK source code and frameworks like Spring to improve code extensibility.
Definition : The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable, allowing algorithm changes without affecting the client.
Structure : It consists of three main participants – Strategy (an abstract interface or class defining common operations), Concrete Strategy (implementations of the algorithm), and Context (holds a reference to a Strategy and delegates calls).
Case Study : An e‑commerce discount scenario with four membership levels (non‑member, ordinary, silver, gold) is used to demonstrate the problem of tangled if‑else logic and how the Strategy pattern can cleanly separate each discount rule.
public long calculate(String userType, long amount) {
if ("ordinary".equals(userType)) {
if (amount > 200) {
return amount / 100 * 90;
}
return amount;
}
if ("silver".equals(userType)) {
if (amount > 300) {
return amount / 100 * 80 - 20;
}
return amount / 100 * 80;
}
if ("golden".equals(userType)) {
if (amount > 300) {
return amount / 100 * 60;
}
return amount / 100 * 70;
}
return amount;
}Refactoring with the Strategy pattern starts by defining a common interface:
public interface PromotionStrategy {
long calculate(long amount);
}Then each membership rule is implemented as a concrete strategy:
public class NonMemberStrategy implements PromotionStrategy {
@Override
public long calculate(long amount) {
return amount;
}
}
public class OrdinaryMemberStrategy implements PromotionStrategy {
@Override
public long calculate(long amount) {
if (amount > 200) {
return amount / 100 * 90;
}
return amount;
}
}
public class SilverMemberStrategy implements PromotionStrategy {
@Override
public long calculate(long amount) {
if (amount > 300) {
return amount / 100 * 80 - 20;
}
return amount / 100 * 80;
}
}
public class GoldenMemberStrategy implements PromotionStrategy {
@Override
public long calculate(long amount) {
if (amount > 300) {
return amount / 100 * 60;
}
return amount / 100 * 70;
}
}The Context class holds a PromotionStrategy reference and forwards the calculation:
public class PromotionContext {
private PromotionStrategy promotionStrategy;
public PromotionContext(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
public long calculate(long amount) {
return promotionStrategy.calculate(amount);
}
}A client can now instantiate the appropriate context and obtain results without any conditional logic:
public class PromotionClient {
public static void main(String[] args) {
PromotionContext nonMember = new PromotionContext(new NonMemberStrategy());
PromotionContext ordinary = new PromotionContext(new OrdinaryMemberStrategy());
PromotionContext silver = new PromotionContext(new SilverMemberStrategy());
PromotionContext gold = new PromotionContext(new GoldenMemberStrategy());
System.out.println(nonMember.calculate(500)); // 500
System.out.println(ordinary.calculate(500)); // 450
System.out.println(silver.calculate(500)); // 380
System.out.println(gold.calculate(500)); // 300
}
}This refactoring demonstrates the Open‑Closed Principle: the system is open for extension (new strategies) but closed for modification (existing code remains untouched).
Advantages of the Strategy pattern include easy addition or modification of algorithms, separation of algorithm implementation from usage, and elimination of complex conditional statements.
Disadvantages include the proliferation of small strategy classes, the need for the client to be aware of all strategy types, and added complexity due to the Context layer, which may affect performance.
In summary, the Strategy pattern is suitable for any situation where multiple interchangeable algorithms are needed, such as different file upload handlers, varied food processing methods, or the illustrated discount calculations.
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.
