Strategy Pattern

The Strategy Design Pattern is a behavioral design pattern that allows you to define a family of algorithms or behaviors, encapsulate each one as a separate class, and make them interchangeable at runtime.

The pattern helps in selecting an appropriate algorithm or behavior dynamically, without coupling the client code to specific implementations. This promotes flexibility and enhances code maintainability.

Strategy Pattern Example:

Think of the Strategy Pattern as a cooking analogy. You have a chef who can cook different types of dishes (algorithms), such as Italian, Chinese, or Indian. When a customer places an order, the chef selects the cooking style based on the customer’s preference. The cooking style can be swapped or changed easily, but the customer doesn’t need to know the details of how the dish is prepared.

Strategy Pattern C++ Example:

Let’s understand the Strategy Pattern with a simple example of a payment system. The payment system supports different payment methods (strategies), such as Credit Card, PayPal, and Google Pay. Depending on the customer’s choice, the appropriate payment method will be selected to process the payment.

Strategy Pattern Explanation of Code:

#include <iostream>
#include <string>

// Strategy Interface
class PaymentStrategy {
public:
    virtual void pay(float amount) = 0;
};

// Concrete Strategies: Credit Card, PayPal, Google Pay
class CreditCardPayment : public PaymentStrategy {
public:
    void pay(float amount) override {
        std::cout << "Paid $" << amount << " using Credit Card." << std::endl;
    }
};

class PayPalPayment : public PaymentStrategy {
public:
    void pay(float amount) override {
        std::cout << "Paid $" << amount << " using PayPal." << std::endl;
    }
};

class GooglePayPayment : public PaymentStrategy {
public:
    void pay(float amount) override {
        std::cout << "Paid $" << amount << " using Google Pay." << std::endl;
    }
};

// Context: Payment System
class PaymentSystem {
private:
    PaymentStrategy* paymentStrategy;

public:
    void setPaymentStrategy(PaymentStrategy* strategy) {
        paymentStrategy = strategy;
    }

    void makePayment(float amount) {
        paymentStrategy->pay(amount);
    }
};

int main() {
    PaymentSystem paymentSystem;

    CreditCardPayment creditCardPayment;
    PayPalPayment payPalPayment;
    GooglePayPayment googlePayPayment;

    // Customer selects different payment methods
    paymentSystem.setPaymentStrategy(&creditCardPayment);
    paymentSystem.makePayment(100.0f);

    paymentSystem.setPaymentStrategy(&payPalPayment);
    paymentSystem.makePayment(50.0f);

    paymentSystem.setPaymentStrategy(&googlePayPayment);
    paymentSystem.makePayment(75.0f);

    return 0;
}

Output:

Paid $100 using Credit Card.
Paid $50 using PayPal.
Paid $75 using Google Pay.

Strategy Pattern Explanation of the Code:

In this example, we have four main components:

  1. PaymentStrategy (Abstract Class): Represents the interface for all payment strategies (algorithms) and defines the pay method that concrete strategies must implement.
  2. CreditCardPayment, PayPalPayment, and GooglePayPayment (Concrete Classes): Represent concrete payment strategies implementing different payment methods.
  3. PaymentSystem (Context): Represents the context that uses a specific payment strategy to process payments.

In the main function, we create a PaymentSystem object and three payment strategy objects (CreditCardPayment, PayPalPayment, and GooglePayPayment). We set different payment strategies for the payment system using setPaymentStrategy, and then we make payments using makePayment.

The key point here is that the payment system can switch between different payment strategies seamlessly without modifying the client code (main function).

Applications of Strategy Design Pattern:

  1. Sorting algorithms: In sorting applications, the Strategy pattern can be used to allow users to choose different sorting algorithms at runtime.
  2. GUI frameworks: Strategy pattern can be used to change the behavior of UI elements based on user preferences.
  3. File compression: In compression software, different compression algorithms can be implemented using the Strategy pattern.

Strategy Pattern Pros and Cons:

Pros:

  • Flexibility: Allows easy switching of algorithms or behaviors at runtime.
  • Encapsulation: Each strategy is encapsulated within its own class, promoting clean code and maintainability.
  • Easy to extend: New strategies can be added without affecting the existing code.

Cons:

  • Increased number of classes: Implementing the Strategy pattern may lead to a larger number of classes, which can be complex to manage.
  • Overhead: The pattern can introduce a slight overhead due to the additional abstraction layer. However, this overhead is generally negligible compared to the benefits it provides.