Ever wondered if there is more than one design pattern when developing your application? Is the only thing you learned the Singleton pattern? If you think that Singleton is the number one pattern in this world, my best guess is that you don’t have a job. If you ask in a community the Singleton pattern is deprecated and even hated by a lot of developers!

In this article I’ll tell you a bit about the top five most commonly used design patterns when you are developing PHP applications. The reason I am writing this article is because i have searched the web and only found documentation on a complex level. So.. I decided to make this an easy to understand article for everyone!

In the description of the patterns below i will be showing you some examples of how to implement the pattern in applications.

The Factory Pattern

PHP Design Patterns 1

If you want to build an object, you should use factories. Yes only when you want to build an object not create an object! You don’t want to use a factory if you just want to create a new object. When building an object the first thing you do is create it and then initialize it. This usually involves multiple steps and applying certain logic in the process.

By doing that it makes sense to have all that logic in one place and then re-use it whenever you need to have a new object built the same way. Basically thats the essence in using the factory pattern.

In the example below and all code i have written, it always have an interface, where you make the code depend on it and not on the factory. Doing it this way allows you to replace one factory with another whenever you need it.

Lets have an example of a car factory

interface CarFactoryInterface {
    public function create() : Car
}

Now we will implement the factory interface with the CarFactory:

class CarFactory implements CarFactoryInterface {
    public function create() : Car {
        
        $car = new Car();
        // initialize your car
        return $car;
    }
}

Well, that’s pretty straight forward and simple to do. At the same time its a very powerfull pattern, if you ask me!

The Strategy Pattern

The strategy pattern is used to hide implementation details of your algorithms, when you need to perform a certain operation. By using strategies the client is free to choose an algorithm without knowing the exact implementation and apply it to perform an operation.

If you are building a library that as an example transfers data from one data source to another. We would need to transfer the data from our database to a CSV file or from a spreadsheet to a JSON file. How could we accomplish that?

The first thing we have to do is create strategies to read the data from the storage providers. In the example I will be naming them readers. Next on we would have to create strategies to write the data to our storage providers. I’ll name the Writers.

So..we would have two readers, one to read data from our database and one to read from the spreadsheet. Accordingly we also have two writers, one to write the data to the CSV file and one to write the data to a JSON file.

Important

The client working with our strategies won’t or shouldn’t care about their implementation. Therefore, we always have to implement interfaces defining our strategies. That way our logic will be like a black box where the client know the methods defines by our strategy interfaces and don’t have to be concerned about the logic behind.

Last thing that we have to do is creating the client that would make use of our strategies.

Okay, so now that you got the fundamentals on how the strategy pattern works, let’s see how we can implement this in a solution.

An Example on the strategy pattern

interface ReaderInterface { 
public function start() : void;
public function read() : array;
public function stop() : void;
}
interface WriterInterface {
public function start() : void;
public function write(array $data) : void;
public function stop() : void;
}
class DatabaseReader implements ReaderInterface {
...
}
class SpreadsheetReader implements ReaderInterface {
...
}
class CsvWriter implements WriterInterface {
...
}
class JsonWriter implements WriterInterface {
...
}
class Transformer {

...
    public function transform(string $from, string $to) : void {
$reader = $this->findReader($from);
$writer = $this->findWriter($to);

$reader->start();
$writer->start();
        try {
foreach ($reader->read() as $row) {
$writer->write($row);
}
} finally {
$writer->stop();
$reader->stop();
}
}
     ...
}

Did you see the smart thing by having an interface to handle the strategies? The transformer class (the client) don’t have to know anything about the implementations – it works out of the box. All the client have to care about the defined methods in our interface.

The Adapter Pattern

The adapter pattern is used to turn a foreign interface into a common interface. A short example where we assume that we get data from som storage using the following class:

class Storage {
    private $source;

public function __constructor(AdapterInterface $source) {
$this->source = $source;
}
    public function getOne(int $id) : ?object {
return $this->source->find($id);
}

public function getAll(array $criteria = []) : Collection {
return $this->source->findAll($criteria);
}
}

Did you notice that storage doesn’t work directly with our source provider but works with the adapter of our source?

At the same time storage doesn’t know anything about the adapters. It only refers to the adapter interface. This makes the implementation of the adapter a complete black box.

An example of the adapter interface

interface AdapterInterface {
public function find(int $id) : ?object;
public function findAll(array $criteria = []) : Collection;
}

If we assume that we use a library to access our MySQL database, the library will dictate its own interface and that will look like the example below:

$row = $mysql->fetchRow(...);
$data = $mysql->fetchAll(...);

We simply can’t integrate library into our storage. Therefore we need to create a new adapter for it, like done below:

class MySqlAdapter implements AdapterInterface {

...
     public function find(int $id) : ?object {

$data = $this->mysql->fetchRow(['id' => $id]);
         // some data transformation logic here
     }
     public function findAll(array $criteria = []) : Collection {

$data = $this->mysql->fetchAll($criteria);
         // some data transformation logic here
     }
   
     ...
}

When done, we can inject that adapter into the storage, by doing this:

$storage = new Storage(new MySqlAdapter($mysql));

When your system has been running for a while and you want to use another library, the only thing you would have to do is create another adapter for the library and inject it into the storage.

The smart thing here is that we don’t need to touch anything inside storage in order to use a different library for retrieving data from our database. Thats the really smart thing about the adapter pattern.

The Observer Pattern

It’s in the name “observer”. The observer pattern is used to notify the whole system about events. For gaining a better understanding you will find two examples below of the same issue.

Okay, let’s for instance say that we own a cinema and we would like to show movies for the critics. First thing to do is to define a class named Cinema with a method to present movies.

Before we present the movie we would like to send a message to all the critics phones. When the movie is half way done, we would like o give the critics a 5 minute break. And finally when the movie end, we would like to gather some feedback from the critics.

An example of the observer pattern

class Cinema {
   
    public function present(Movie $movie) : void {
       
        $critics = $movie->getCritics();
        $this->messenger->send($critics, '...');

$movie->play();

$movie->pause(5);
        $this->progress->break($critics)
        $movie->finish();

$this->feedback->request($critics);
    }
}

So far so good, it all looks clean and straight forward.

But what is a movie in a cinema without the lights turned off? Also when we make a break for the critics we would like to show some advertising and when the movie is done, we would like to clean the cinema.

As i see it, we got an issue here. In order to modify our Cinema class, we would have to break the SOLID principles. The exactly rule we are going to break is the Open / Closed principle. At the same time we would make the Cinema class depending on several services, which makes the coupling really tight.. not a good idea!

Let’s shake things a little. Instead of adding more logic making it a more complex class. We could spread out the complexity across the solution, and then reduce dependencies in the Cinema class at the same time.

Here is how it can be done in practices:

class Cinema {
    
    public function present(Movie $movie) : void {
        
        $this->getEventManager()
            ->notify(new Event(Event::START, $movie));
        $movie->play();

$movie->pause(5);
        $this->getEventManager()
->notify(new Event(Event::PAUSE, $movie));
        $movie->finish();

$this->getEventManager()
->notify(new Event(Event::END, $movie));
}
}
$cinema = new Cinema();
$cinema
    ->getEventManager()
    ->listen(Event::START, new MessagesListener())
    ->listen(Event::START, new LightsListener())
    ->listen(Event::PAUSE, new BreakListener())    
    ->listen(Event::PAUSE, new AdvertisementListener())
    ->listen(Event::END, new FeedbackListener())
    ->listen(Event::END, new CleaningListener());
$cinema->present($movie);

Allright – now the present method in our cinema is pretty straight forward. It doesn’t care at all about what happens outside the class. As before it only does what it is supposed to do and tell other parts of the system about events.

At the same time we got some listeners, these listeners can listen to the events from our cinema and execute other methods when invoked by the listener.

Using this approach makes it easy for you or another developer to add more complexity to the solution. All the developer has to do is creating a new listener and put the logic in the right place.


Reading and watching videos on Youtube about these patterns was a tuff thing (for me at least). All texts about this is so complex and in-depth going, that new programmers would drown if they where reading them.

In the article i have tried to explain some of the design patterns of PHP. I hope you found it easy to understand or tried some of the examples in one of your projects. If you found it useful && / || interesting, please share it 🙂

Leave a Reply