MOBI BOOT CAMP CORP. logoLearning Buddy
  • SIGN IN
  • Introduction
  • 1. Build Tools & Project Structure
  • 2. The Web Layer (Servlets & JSP)
  • 3. Design Patterns & Architecture
    • Architectural Patterns (MVC, DAO, DTO)
    • Singleton Pattern
    • Factory Method Pattern
    • Builder Pattern
    • Strategy Pattern
    • Observer Pattern
  • 4. Persistence Foundations (SQL & JDBC)
  • 5. Object-Relational Mapping (ORM)
  • 6. Modern Web Services & Microservices
  • 7. Hands-on Project

Strategy Pattern

The Strategy Pattern is a behavioral design pattern that enables selecting an algorithm at runtime. It defines a family of algorithms, encapsulates each one, and makes them interchangeable. This lets the algorithm vary independently from the clients that use it.

This pattern is a powerful tool for creating flexible and maintainable software. Instead of implementing a single algorithm directly, the code receives runtime instructions as to which algorithm in a family of algorithms to use.

When to Use It

  • When you have multiple variants of an algorithm for a task and you want to switch between them at runtime.
  • When you have a class that defines many behaviors, and these appear as multiple conditional statements in its operations. The Strategy pattern lets you move each branch of the conditional to its own class. -- When you want to isolate the business logic of a class from the implementation details of its algorithms.

Structure

  1. Context: The class that contains a reference to a Strategy object. The Context does not know the concrete type of the strategy. It should work with all strategies via the Strategy interface.
  2. Strategy: The common interface for all supported algorithms.
  3. ConcreteStrategy: Implements the Strategy interface, providing a specific algorithm.

Example: A Payment Processing System

Imagine an e-commerce application that needs to process payments. There could be multiple payment methods, such as Credit Card, PayPal, or a Gift Card. The Strategy pattern is perfect for encapsulating the logic for each payment method.

1. Strategy Interface (PaymentStrategy)

This interface defines a single method, pay, that all payment strategies must implement.

package com.example.patterns.strategy;

public interface PaymentStrategy {
    void pay(int amount);
}

2. Concrete Strategies (CreditCardPayment, PayPalPayment)

These classes implement the PaymentStrategy interface, each providing a different payment algorithm.

CreditCardPayment.java

package com.example.patterns.strategy;

public class CreditCardPayment implements PaymentStrategy {
    private String name;
    private String cardNumber;

    public CreditCardPayment(String name, String cardNumber) {
        this.name = name;
        this.cardNumber = cardNumber;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid with credit card ending in " + cardNumber.substring(cardNumber.length() - 4));
    }
}

PayPalPayment.java

package com.example.patterns.strategy;

public class PayPalPayment implements PaymentStrategy {
    private String emailId;

    public PayPalPayment(String email) {
        this.emailId = email;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid using PayPal account " + emailId);
    }
}

3. Context Class (ShoppingCart)

The ShoppingCart class holds a reference to a PaymentStrategy. It doesn't know the concrete details of the payment method; it just calls the pay method on the strategy object.

package com.example.patterns.strategy;

public class ShoppingCart {
    private int totalAmount = 0;

    public void addItem(String item, int price) {
        System.out.println("Adding item: " + item + " for $" + price);
        this.totalAmount += price;
    }

    public int getTotalAmount() {
        return totalAmount;
    }

    // The cart takes a payment strategy to complete the checkout
    public void checkout(PaymentStrategy paymentMethod) {
        paymentMethod.pay(getTotalAmount());
    }
}

4. Putting It All Together

The client code creates a ShoppingCart, adds items, and then decides which payment strategy to use at runtime for the checkout process.

package com.example.patterns.strategy;

public class StrategyDemo {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        cart.addItem("Laptop", 1200);
        cart.addItem("Mouse", 25);

        System.out.println("Total amount: $" + cart.getTotalAmount());
        System.out.println("---");

        // --- Client decides the strategy at runtime ---

        // Pay with a Credit Card
        System.out.println("Checking out with Credit Card:");
        PaymentStrategy creditCard = new CreditCardPayment("John Doe", "1234567890123456");
        cart.checkout(creditCard);

        System.out.println("---");

        // Pay with PayPal
        System.out.println("Checking out with PayPal:");
        PaymentStrategy payPal = new PayPalPayment("john.doe@example.com");
        cart.checkout(payPal);
    }
}

Output:

Adding item: Laptop for $1200
Adding item: Mouse for $25
Total amount: $1225
---
Checking out with Credit Card:
1225 paid with credit card ending in 3456
---
Checking out with PayPal:
1225 paid using PayPal account john.doe@example.com

This example clearly shows how the ShoppingCart is decoupled from the payment logic. We can add new payment methods (like BitcoinPayment) without changing the ShoppingCart class at all.

Privacy Policy | Terms & Conditions