Strategy Design Pattern In PHP8

Arash
2 min readNov 12, 2021

--

Hello, world!
This is my first post on Medium and I want to share some of my experiences that have saved my life :)
Here I will explain a strategy pattern I use frequently in projects.

In order to explain the solution, I need to explain a real problem, followed by how to solve it.
Initially, we had a way to deliver orders to clients when I was working on an online shop project.
However, the product owner decided to add another method of delivery after a while. I had two options:
Add an if-else condition and more code to current class to support the new delivery method, or utilize a design pattern to keep the code clean and extend the project’s features.

Of course, I used strategy design pattern, and now we have more than five different delivery methods, and I can add other delivery methods without changing the main delivery class.

In software design, a strategy pattern is a behavior that enables algorithms to be selected at runtime. The code does not implement a single algorithm directly, but instead receives instructions on which algorithm to use from a family.

Now let’s dive into the code.

First, we need to create an interface:

<?phpnamespace App\Delivery;interface DeliveryInterface
{
public function process(int $orderId): void;
}

Our delivery methods must now implement this interface:

<?phpnamespace App\Delivery;class DeliveryMethod1 implements DeliveryInterface
{
public function process(int $orderId): void
{
echo "Order #{$orderId} is being processed by DeliveryMethod1";
}
}

And

<?phpnamespace App\Delivery;class DeliveryMethod2 implements DeliveryInterface
{
public function process(int $orderId): void
{
echo "Order #{$orderId} is being processed by DeliveryMethod2";
}
}

Finally, we need a context class to select the appropriate delivery class based on the method type:

<?phpnamespace App\Delivery;class DeliveryContext
{
private $delivery = null;

public function __construct(string $method)
{
$this->delivery = match ($method) {
'method-1' => new DeliveryMethod1(),
'method-2' => new DeliveryMethod2(),
default => throw new \Exception("Unknown delivery method: {$method}")
};
}
public function process(int $orderId): void
{
$this->delivery->process($orderId);
}
}

In the main class we need to put the code as shown below and it doesn’t need to change in features for new delivery methods to be added:

$delivery = new App\Delivery\DeliveryContext($_POST['method']);
$delivery->process(100);

Hope it’s useful and you can use it in your projects.

Please provide me with feedback so that I can improve my upcoming posts.

--

--