The Strategy Pattern is a behavioral design pattern that enables an object to change its behavior at runtime.

This pattern is particularly useful when you want to rewrite a part of a class from outside. It lets you define a family of similar algorithms, each on a separate class and make them interchangeable.

The primary components of this pattern are:

Example

A typical example that can demonstrate the strategy pattern is a payment service with multiple payment methods that can be implemented as different strategies:

// The Strategy Interface
interface PaymentMethod {
    public function pay($amount);
}
// Concrete Strategies
class PayPal implements PaymentMethod {
    public function pay($amount) {
        echo "Paying $amount using PayPal";
    }
}

class CreditCard implements PaymentMethod {
    public function pay($amount) {
        echo "Paying $amount using Credit Card";
    }
}
// The Context
class ShoppingCart {
    private $items = [];
    private $paymentMethod;

    public function addItem($item) {
        $this->items[] = $item;
    }

    public function setPaymentMethod(PaymentMethod $paymentMethod) {
        $this->paymentMethod = $paymentMethod;
    }

    public function checkout() {
        $amount = array_sum($this->items);
        $this->paymentMethod->pay($amount);
    }
}
// Can use different payment strategies interchangeably
$cart = new ShoppingCart();
$cart->addItem(100);
$cart->addItem(200);

// Paying with PayPal
$cart->setPaymentMethod(new PayPal());
$cart->checkout();

// Paying with Credit Card
$cart->setPaymentMethod(new CreditCard());
$cart->checkout();

Advantages

Although simple to implement, the benefits of the Strategy Pattern are huge. It implements both the Single Responsibility principle and the Open-Closed principle. Offering significant flexibility and scalability in software design with minimal complexity.