Skip to content
Home » Facade Pattern in PHP | Using Design Patterns in 2023

Facade Pattern in PHP | Using Design Patterns in 2023

Using the Facade Design Pattern in PHP

The facade pattern in PHP is a structural design pattern that provides a simplified interface over a complex set of subsystems. The article features an application that relies on a number of complex microservices. To simplify the existing complex architecture, we set on a journey to simplify it as much as possible and that’s where the facade pattern saves the day. 

Facade Pattern in PHP
Facade Pattern in PHP

Definition | Facade Design Pattern in PHP

“Facade design pattern is a structural design pattern that provides a simplified interface to a number of complex sets of subsystems. The facade is a wrapper that hides the interactions between these subsystems and makes it easy to use

Facade Pattern in PHP
Facade Pattern

Let’s understand the facade design pattern in PHP through a real-life example of a software application that uses many complex subsystems or services.

QuickGrocer | Real-World Example

Suppose we are working in an online grocery delivery startup, QuickGrocer (QGrocer). We are supposed to implement the backend services. These services come into play when the customer creates a cart and places an order via QGrocer’s mobile application.

There is a sophisticated backend flow from end-to-end, that is, from receiving an order to assigning a rider. Here’s an abstract view of what it looks like.

end-to-end-flow

So, there’s a lot going on and microservices tend to call each other and that’s why we see all those services wired together. They are independent but they had to be put together correctly like pieces of a puzzle to form the bigger picture.

That’s why we see all those inter-relationships. But wonder what it looks like in code? Let’s peek into what happens when a customer places an order and the flow’s initiated.

QGrocer’s microservices in action

Let’s see what happens after a customer places an order and the request reaches the backend.

  1. OrderFulfilment service initiate the request cycle.
  2. CartProcessor fetches the inventory that has to be updated.
  3. Inventory updates the warehouse.
  4. Packer changes the status to packing and suggests that the order is ready for delivery.
  5. Rider assigns a rider based on the user’s location and the nearest warehouse.

Here’s what it looks like in pseudocode.

fulfillment-flow

It seems complicated given that we have five different services. But there are deeper problems.

Problem 🙁

Subsystems & complexity

It is natural to have more complexity when you have more subsystems. In this type of architecture, the Client tends to bind itself to all these concrete subsystems which is a precursor to inflexible systems 

What if we want to add a new service or what if we want to enable self-pickup instead of assigning a rider? These changes will force us to make changes to the Client code and that violates a design principle, see next.

Open-closed principle

The Open-closed principle states that “a class should be open for extension but closed for modification.”  We have seen already how a small change will force us to violate this principle and thus introduce bugs in the system.

Other similar examples of violation would be adding a new class, say Drone that supports a drone-based delivery. Long short story, one change and we are doomed to change a rigid, inflexible software.

Lack of abstraction

Flexible systems use abstractions or interfaces to either encapsulate or simplify underlying details. The more you keep a system abstract, the more flexible and extendible it becomes because modules in the upper hierarchy don’t depend on that in the lower and is concerned with abstractions or interfaces.

That’s  a golden rule to follow, “program to interfaces, not implementations.” The current design is coupled to all the concrete subsystems and that’s where the problem begins.

Solution 🙂

Principle of least knowledge

Here’s a key to flexible design systems, ‘The Principle of Least Knowledge” which states that a class should communicate with its close “friends” only. The friends here refer to the object itself, the objects that it receives in a method or those that the class initiates itself. 

Why close friends? That’s to restrict the number of interactions of dependencies of a class. Tight coupling and dependencies mean fragile systems, one in which a change can shake an entire system. 

The current design also calls objects that are returned from methods and those are certainly not the ones fulfilling the criteria that the principle sets and that’s where coupling and dependencies are added to the module.

Interface & encapsulation

One important note here is that we want to have access to the services but we also want to simplify the process by introducing an interface or a wrapper class. Also, note that the word interface may not always refer to interface in programming. It means abstraction by hiding details, not necessarily making the details inaccessible.

So, we need to provide a simpler interface to carry out the process while still keeping the sub-systems accessible because sometimes we may need direct access to them. So how do we go about them?

Introducing Facades

A Facade class is a wrapper over the mesh of complex subsystems and their interactions. It provides us with a simpler interface, one which hides the underlying implementation and hands us one method to deal with similar complexity as we have seen above in the order fulfillment flow. 

The facade becomes a close friend of the Client module and from the least knowledge principle, the Client module interacts with Facade only, not worrying much about what goes beneath. Consequently, we have flexible systems. 

Any change made to the services remains confined in the facade and therefore, the overall system tends to be more flexible and extendible.

Facade Pattern in PHP
Facade Class

On top of that, the subsystems are still visible. You can always interact with them because the facade is a simplification rather than an encapsulation. 

The Order Fulfillment Facade

Let’s see the OrderFulfillmentFacade which has a composition (has-a) relation with the objects of the subsystems. 

ordefulfillment-facade-class

Implementing the fullfillOrder()

The objective of the facade is to simplify the process or the function calls that we have already. So, the facade implements a fulfillOrder() method that acts as a wrapper over the complex end-to-end flow that we have already.

fulfillorder-method

Let’s use Facade Design Pattern

So, we have applied the facade design pattern, and now is the time for a test drive. Let’s see how the Client class will use this facade.

client-class

Benefits of the Facade Design Pattern

  • Decouples client implementation from the subsystems.
  • You can have a simplified interface while retaining access to the subsystems.
  • Makes the system more flexible and maintainable because the change affects the facade rather than cascading to the entire system.
  • Add as many facades as necessary to simplify subsystems.

Complete Architecture | Facade Design Pattern in PHP

Facade Pattern in PHP
Facade Pattern in PHP

Facade Design Pattern in PHP

The following is a complete example of the facade pattern in PHP.

Code | Facade Design Pattern in PHP

<?php

class OrderFulfillment {

    function init() {
        echo "Order fulfillment process has initialised".PHP_EOL;
    }

    function getCart() {
        return "cart";
    }
}

class Inventory {
    function updateWarehouse() {
        echo "Warehouse updated".PHP_EOL;
    }
}

class CartProcessor {

    function reachInventory($cart) {
        echo "Inventory updated".PHP_EOL;

        return new Inventory();
    }
}

class Packer {
    
    function pack($cart) {
        echo "Packing order".PHP_EOL;
    }
}

class Rider {

    function assign() {
        echo "Rider has been assigned".PHP_EOL;
    }
}


//Facade class
class OrderFulfillmentFacade {

    private $orderfullfilment;
    private $inventory;
    private $cartprocessor;
    private $packer;
    private $rider;

    function __construct($ord, $cp, $packer, $rider) {
        $this->orderfullfilment = $ord;
        $this->cartprocessor = $cp;
        $this->packer = $packer;
        $this->rider = $rider;
    }

    function fulfillOrder() {
        $this->orderfullfilment->init();
        $this->inventory = $this->cartprocessor->reachInventory($this->orderfullfilment->getCart());
        $this->inventory->updateWarehouse();
        $this->packer->pack($this->orderfullfilment->getCart());
        $this->rider->assign();
    }
}

function main() {
    $orderfulfillmentfacade = new OrderFulfillmentFacade(new OrderFulfillment(), new CartProcessor(), new Packer(), new Rider());

    $orderfulfillmentfacade->fulfillOrder();
}

main();
?>

Output | Facade Design Pattern in PHP

Order fulfillment process has initialised
Inventory updated
Warehouse updated
Packing order
Rider has been assigned

Pros and Cons of the Facade Pattern in PHP

ProsCons
Simplifies a complex subsystem by providing a wrapperAdds one or more wrappers in the form of a facade.
Subsystems remain accessible.A facade couples with all the subsystems and become the most crucial class which may not be ideal in some cases.
A facade can also include some logic rather than just calling the subsystemsFacade class violates the single responsibility principle
Satisfies the open-closed & least knowledge principles

Where is the Facade Pattern Used?

  • In a complex application that relies on many co-related subsystems. The facade provides a simplified interface for the interactions that happen between these subsystems.
  • When you want to create logical layers of related sets of subsystems.

Frequently Asked Questions on the Facade Design Pattern

What is the facade pattern?

The facade pattern is a structural design pattern that provides a simplified interface to a number of complex sets of subsystems. The facade is a wrapper that hides the interactions between these subsystems and makes it easy to use.

What is the risk of using the facade pattern?

The risk or misuse of this pattern happens when you try to introduce it unnecessarily. When you want to implement a solution looking for a problem. The facade is useful when you have awfully complex subsystems and you want to provide a higher-level interface to avoid dealing with them every time.

Another risk of using this pattern is that the facade class becomes the most crucial class controlling the entire flow of your process and sometimes it is not ideal to depend on one class for all the functionalities. It takes more than one responsibility, violating the single responsibility principle. 

What is the difference between the adapter and facade design pattern?

The adapter pattern provides an intermediary adapter interface that takes interface B and makes it compatible with interface A. The purpose of the adapter is to alter an interface to the one being expected.

The facade pattern doesn’t alter interfaces rather it provides a wrapper or a higher-level interface to simplify complex sets of subsystems. 

Using the Facade Pattern in PHP Today

Phew! That was quite a pattern. Let’s recap what we have seen. The facade patten is a structural design pattern that provides an interface, a high-level wrapper over a set of complex subsystems. The objective of this pattern is to simplify the underlying complexity and decouple the rest of the application from the subsystems as much as possible.

This article features an example of QuickGrocer (QGrocer), an online delivery application that uses microservice architecture to support its business processes. There are many microservices(subsystems) interacting in order to fulfill an order, which starts when a customer places an order.

Initially, the client class was tightly coupled with the microservices and used to interact with them directly. This design was problematic because it was rigid, inflexible, and non-maintainable. To solve this problem, we have seen the open-closed and least knowledge principles.

Based on these principles, we were able to design a simplified wrapper, called a facade which encapsulates the process of calling all these functions and simulating the end-to-end flow of order fulfillment. The client code is now interacting with the facade class only and leaves the rest to it.

With the facade, we have solved the issue of having an inflexible and rigid design without having to give up access to the subsystems because the facade provides a wrapper only and the subsystems are always accessible for use.

So, that’s all about it. We hope you are now well aware of this facade pattern and can implement it whenever possible.

See you in another design pattern article. Stay tuned at FuelingPHP.

Books on Design Patterns

Want to learn more about Design Patterns? There are many great resources online. We recommend the following books for your collection as they both can teach you the theoretical and the application of using design patterns in your day-to-day programming. Feel free to use the following Amazon affiliate links if you’d like to purchase them and a way to support our efforts.

Design Patterns: Elements of Reusable Object-Oriented Software

Design Patterns: Elements of Reusable Object-Oriented Software book

This is the book that started it all. I believe that every programmer should have a referenced copy to this book at some point in their career. There have been many updates and excellent newer content through the years, but this is a classic. It still stands the test of time and is just as relevant for today as it was in the original printing in the 90s.

Check it out on amazon

Learning PHP Design Patterns

This is an excellent book to go beyond the theory and apply it to writing good PHP code. Learning PHP Design Patterns is published by the popular O’Reilly media company. O’Reilly consistently publishes some of the most useful reference material related to software development. They are known to provide materials that thoroughly cover a topic in a way that is simple to understand. I recommend this book to every PHP developer.

Check it out on amazon

Design Patterns in PHP Learning Series.

This article is part of our series of design patterns in PHP. We are going through all of the patterns and showing how they can help you build better applications. Browse through our full list of patterns below.