Overview
The Strategy Pattern is a behavioral design pattern that allows you to define a family of algorithms, encapsulate them in separate classes, and make them interchangeable. This pattern lets you select an algorithm’s behavior at runtime without modifying the client.
Key Participants
Context
Maintains a reference to a Strategy object.
Allows the strategy to be dynamically changed.
Delegates behavior to the currently selected Strategy.
Strategy
Defines the interface for a family of algorithms.
Provides an abstract method that concrete strategies must implement.
ConcreteStrategy
Implements the Strategy interface with specific behavior.
Represents a specific algorithm.
Implementation in Code
Example: Payment System
// Strategy Interface
interface PaymentStrategy {
void pay(int amount);
}
// ConcreteStrategy: Credit Card Payment
class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
public CreditCardPayment(String cardNumber) {
this.cardNumber = cardNumber;
}
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using Credit Card ending in " + cardNumber.substring(cardNumber.length() - 4));
}
}
// ConcreteStrategy: PayPal Payment
class PayPalPayment implements PaymentStrategy {
private String email;
public PayPalPayment(String email) {
this.email = email;
}
@Override
public void pay(int amount) {
System.out.println("Paid " + amount + " using PayPal account: " + email);
}
}
// Context
class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void checkout(int amount) {
if (paymentStrategy == null) {
System.out.println("No payment strategy selected.");
} else {
paymentStrategy.pay(amount);
}
}
}
// Client
public class StrategyPatternDemo {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
// Pay with Credit Card
cart.setPaymentStrategy(new CreditCardPayment("1234-5678-9101-1121"));
cart.checkout(500);
// Pay with PayPal
cart.setPaymentStrategy(new PayPalPayment("user@example.com"));
cart.checkout(300);
}
}
Key Methods
setStrategy(Strategy): Allows the context to change the strategy dynamically.
execute(): Defines the behavior of the strategy.
Advantages
Open/Closed Principle: New strategies can be added without modifying existing code.
Encapsulation: Encapsulates algorithms, making them independent of the client.
Interchangeability: Algorithms can be swapped at runtime.
Disadvantages
Increased Complexity: Requires creating a class for each strategy.
Overhead: Using multiple strategies might increase memory and computational overhead.
Real-World Examples
Sorting Algorithms: A sorting application can use different sorting strategies like Bubble Sort, Quick Sort, or Merge Sort.
Payment Systems: Different payment methods such as credit card, PayPal, or bank transfer.
Compression Algorithms: A file compressor can support ZIP, RAR, or GZIP compression.
When to Use the Strategy Pattern?
When you need multiple algorithms for a specific task, and the choice can vary at runtime.
When you want to isolate algorithm implementation from the client.
When adding or changing algorithms should not affect the client code.