Introduction to the Strategy Pattern in PHP

Introduction to the Strategy Pattern

Welcome back! We are continuing our journey through Behavioral Patterns in PHP. In previous lessons, we explored the Command and Observer patterns, focusing on object communication and state changes. Now, we will delve into the Strategy Pattern.

What You'll Learn

The Strategy Pattern is designed to address situations where a class needs to perform similar operations using different algorithms or behaviors. Instead of hardcoding these behaviors into the class with conditionals or multiple methods, the Strategy Pattern allows you to encapsulate each behavior in a separate class. This approach promotes flexibility, as behaviors can be swapped at runtime without altering the context class.

In this lesson, you will learn how to implement the Strategy Pattern in PHP. We will break down the pattern into manageable parts and illustrate its practical application through a clear example.

Consider a scenario where you have a ShoppingCart class that can handle payments through different methods, such as credit cards or PayPal. Using the Strategy Pattern, we can encapsulate these payment methods into separate classes and have the ShoppingCart class use any of these strategies interchangeably.

Here is a snippet of the code we will be working with:

We will start by defining the PaymentStrategy interface, which declares a common method for all payment strategies. Then, we will create concrete strategies such as CreditCardStrategy and PayPalStrategy that implement this interface:

PHP
<?php

interface PaymentStrategy {
    public function pay($amount);
}

class CreditCardStrategy implements PaymentStrategy {
    private $cardNumber;

    public function __construct($cardNumber) {
        $this->cardNumber = $cardNumber;
    }

    public function pay($amount) {
        echo "Paid $amount using Credit Card: $this->cardNumber\n";
    }
}

class PayPalStrategy implements PaymentStrategy {
    private $email;

    public function __construct($email) {
        $this->email = $email;
    }

    public function pay($amount) {
        echo "Paid $amount using PayPal: $this->email\n";
    }
}

Next, we will create a ShoppingCart class that can set a payment strategy and use it to perform the payment operation:

PHP
class ShoppingCart {
    private $strategy;

    public function setPaymentStrategy(PaymentStrategy $strategy) {
        $this->strategy = $strategy;
    }

    public function checkout($amount) {
        if ($this->strategy) {
            $this->strategy->pay($amount);
        } else {
            echo "No payment strategy set.\n";
        }
    }
}

Finally, we will demonstrate how to use the ShoppingCart class with different payment strategies:

PHP
$cart = new ShoppingCart();

$creditCard = new CreditCardStrategy("1234-5678-9876-5432");
$payPal = new PayPalStrategy("user@example.com");

$cart->setPaymentStrategy($creditCard);
$cart->checkout(100);

$cart->setPaymentStrategy($payPal);
$cart->checkout(200);

Let's analyze the key components of the Strategy Pattern through this example:

  • Strategy Interface (PaymentStrategy): An interface that defines a common method (in this case, pay) for all concrete strategies.
  • Concrete Strategies (CreditCardStrategy, PayPalStrategy): Classes that implement the PaymentStrategy interface, providing specific implementations of the pay method.
  • Context (ShoppingCart): The class that uses a PaymentStrategy object. This class can set the strategy at runtime and use it to perform its payment operations.
Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal