PHP — Strategy Design Pattern

3 min readJul 18, 2024

I. What It Is?

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

Type: Behavioral

II. Strategy Pattern in PHP

The Strategy pattern in PHP follows the same principles as in other programming languages. It is a behavioral design pattern that allows you to define a family of algorithms, encapsulate each one, and make them interchangeable. This way, the algorithm can vary independently from the clients that use it.

Here is an example of how you can implement the Strategy pattern in PHP:


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

class CreditCardPayment implements PaymentStrategy {
public function pay($amount) {
echo "Paying $amount using Credit Card.\n";
}
}

class PayPalPayment implements PaymentStrategy {
public function pay($amount) {
echo "Paying $amount using PayPal.\n";
}
}

class BitcoinPayment implements PaymentStrategy {
public function pay($amount) {
echo "Paying $amount using Bitcoin.\n";
}
}

class PaymentContext {
private $paymentStrategy;

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

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

public function pay($amount) {
$this->paymentStrategy->pay($amount);
}
}

// Client code
$amount = 100;

// Example of selecting the strategy at runtime based on a condition
$paymentMethod = 'paypal'; // This could come from user input or some other runtime condition

switch ($paymentMethod) {
case 'creditcard':
$paymentStrategy = new CreditCardPayment();
break;
case 'paypal':
$paymentStrategy = new PayPalPayment();
break;
case 'bitcoin':
$paymentStrategy = new BitcoinPayment();
break;
default:
throw new Exception("Unknown payment method");
}

$paymentContext = new PaymentContext($paymentStrategy);
$paymentContext->pay($amount);

// Changing strategy at runtime
$paymentContext->setPaymentStrategy(new BitcoinPayment());
$paymentContext->pay($amount);

Explanation:

  1. PaymentStrategy Interface: Defines the method that all concrete strategies must implement.
  2. Concrete Strategies: Implement the PaymentStrategy interface with different algorithms for payment.
  3. PaymentContext Class: Maintains a reference to a PaymentStrategy object and delegates the payment process to the current strategy.
  4. Client Code: Uses the PaymentContext to perform payments and can change the strategy at runtime.
  1. Runtime Selection: The switch statement determines which payment strategy to use based on the value of $paymentMethod. This value could be set dynamically at runtime, for example, based on user input.
  2. Changing Strategy: The PaymentContext can change its strategy at any time by calling the setPaymentStrategy method with a new strategy.

This demonstrates the flexibility of the Strategy pattern, as it allows the algorithm to vary independently from the clients that use it. The actual algorithm can be chosen and changed dynamically at runtime, making the code more flexible and easier to maintain.

III. Practical Applications

  1. Payment Processing:
  • Scenario: You have an e-commerce platform that needs to handle multiple payment gateways like PayPal, Stripe, and bank transfers.
  • Implementation: Implement each payment gateway as a concrete strategy that follows a PaymentGateway interface. The application dynamically selects the appropriate payment strategy based on user input.

2. Sorting Algorithms:

  • Scenario: A data processing tool needs to support different sorting algorithms like quicksort, mergesort, and bubblesort.
  • Implementation: Create a SortStrategy interface that different sorting algorithms implement. The application can switch between sorting strategies at runtime based on data size and sorting speed requirements.

3. Logging Mechanisms:

  • Scenario: A system needs to log messages to various backends like files, databases, or cloud logging services.
  • Implementation: Define a LoggerStrategy interface that different logging strategies implement. The main logger dynamically selects the appropriate strategy based on configuration settings.

4. Compression:

  • Scenario: A file management system needs to compress files using different algorithms like ZIP, GZIP, or BZIP2.
  • Implementation: Implement a CompressionStrategy interface with different concrete strategies for each compression algorithm. The file management system selects a compression strategy based on user preferences or file size.

5. Validation Rules:

  • Scenario: A data validation service needs to apply different validation rules based on the type of data being validated (e.g., emails, URLs, or phone numbers).
  • Implementation: Create a ValidationStrategy interface that each concrete validation rule implements. The service can then switch validation strategies dynamically based on the type of data being processed.

V. Code Demo

https://github.com/mytruong-z/php-design-patterns

--

--

No responses yet