The Decorator design pattern

Decorator is a structural design pattern that allows you to add extra functionality, such as if you want to add caching or logging to a service, without changing the original class.

As long as a class implements an Interface, it can be decorated.

For example, if I have this PHP interface:

interface DoesSomething
{
public function doSomething(): void;
}

I could have this class that does something:

final class FirstClass implements DoesSomething
{
public function doSomething(): void
{
// Does something.
}
}

If I need to do something else, like caching or logging the result, I can decorate it.

To do this, I need another class that implements the same interface and inject the original version.

final class SecondClass implements DoesSomething
{
public function __construct(
private DoesSomething $originalClass
) {}

public function doSomething()
{
// Do something else before.

$this->originalClass->doSomething();

// Do something else afterwards.
}
}

Within the new class, the methods can be overridden, extra functionality can be added, and the original method can be run to execute the original functionality.

As the two classes implement the same interface, I can swap between different versions and decorate multiple times if needed.

This a pattern that I used recently to extend a service that retrieved some data from an API and saved it to a file, to change some arguments and do more work with it.

The original class was unchanged, the new class was minimal and easy to understand as it only had a single responsibility, and if I needed to switch back to the original version, I could easily do that.